tint: Add bgra8unorm storage texture support

Polyfill this for the SPIR-V, HLSL and GLSL backends by replacing bgra8unorm with rgba8unorm, and swizzling.

Bug: tint:1804
Change-Id: I36638202840d7313001dff6c5b60dcb948988c34
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/117204
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/ast/storage_texture.cc b/src/tint/ast/storage_texture.cc
index c9d26c2..0a48a5b 100644
--- a/src/tint/ast/storage_texture.cc
+++ b/src/tint/ast/storage_texture.cc
@@ -67,6 +67,7 @@
             return builder.create<I32>();
         }
 
+        case TexelFormat::kBgra8Unorm:
         case TexelFormat::kRgba8Unorm:
         case TexelFormat::kRgba8Snorm:
         case TexelFormat::kR32Float:
diff --git a/src/tint/ast/texel_format.cc b/src/tint/ast/texel_format.cc
index 587cf29..c14c06c 100644
--- a/src/tint/ast/texel_format.cc
+++ b/src/tint/ast/texel_format.cc
@@ -28,6 +28,9 @@
 /// @param str the string to parse
 /// @returns the parsed enum, or TexelFormat::kUndefined if the string could not be parsed.
 TexelFormat ParseTexelFormat(std::string_view str) {
+    if (str == "bgra8unorm") {
+        return TexelFormat::kBgra8Unorm;
+    }
     if (str == "r32float") {
         return TexelFormat::kR32Float;
     }
@@ -83,6 +86,8 @@
     switch (value) {
         case TexelFormat::kUndefined:
             return out << "undefined";
+        case TexelFormat::kBgra8Unorm:
+            return out << "bgra8unorm";
         case TexelFormat::kR32Float:
             return out << "r32float";
         case TexelFormat::kR32Sint:
diff --git a/src/tint/ast/texel_format.h b/src/tint/ast/texel_format.h
index fff88a3..48d05ad 100644
--- a/src/tint/ast/texel_format.h
+++ b/src/tint/ast/texel_format.h
@@ -30,6 +30,7 @@
 /// Enumerator of texel formats
 enum class TexelFormat {
     kUndefined,
+    kBgra8Unorm,
     kR32Float,
     kR32Sint,
     kR32Uint,
@@ -59,9 +60,9 @@
 TexelFormat ParseTexelFormat(std::string_view str);
 
 constexpr const char* kTexelFormatStrings[] = {
-    "r32float",    "r32sint",    "r32uint",    "rg32float",   "rg32sint",   "rg32uint",
-    "rgba16float", "rgba16sint", "rgba16uint", "rgba32float", "rgba32sint", "rgba32uint",
-    "rgba8sint",   "rgba8snorm", "rgba8uint",  "rgba8unorm",
+    "bgra8unorm", "r32float",    "r32sint",    "r32uint",    "rg32float",   "rg32sint",
+    "rg32uint",   "rgba16float", "rgba16sint", "rgba16uint", "rgba32float", "rgba32sint",
+    "rgba32uint", "rgba8sint",   "rgba8snorm", "rgba8uint",  "rgba8unorm",
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/ast/texel_format_bench.cc b/src/tint/ast/texel_format_bench.cc
index c48e0f6..0b1b18e 100644
--- a/src/tint/ast/texel_format_bench.cc
+++ b/src/tint/ast/texel_format_bench.cc
@@ -31,29 +31,30 @@
 
 void TexelFormatParser(::benchmark::State& state) {
     std::array kStrings{
-        "rcc2flot",      "3flo3",        "r32flVat",     "r32float",    "132float",
-        "32Jlqqat",      "ll3277loat",   "ppqq2snHH",    "r3cv",        "b2siGt",
-        "r32sint",       "r32siivt",     "8WW2sint",     "rxxsint",     "rXuingg",
-        "3uiXt",         "r32u3nt",      "r32uint",      "E32uint",     "rPTTuint",
-        "r32uidxx",      "44g32float",   "VVg32SSloat",  "r32flo2Rt",   "rg32float",
-        "r93Float",      "rg32foat",     "rgVROOlHat",   "rg3ysin",     "77grr2sllnnt",
-        "04g32sint",     "rg32sint",     "g3oont",       "rg32zzt",     "rgiipps1n",
-        "XXg32uint",     "rII39955nnnt", "aagHH2uinYSS", "rg32uint",    "rkk3it",
-        "gj3uRRn",       "r3bunt",       "rgba16fljat",  "rgba6float",  "rbq6float",
-        "rgba16float",   "rgba1NNloat",  "rgbvv6flot",   "rgbaQQ6foat", "rgb6srnff",
-        "rgba16sijt",    "NNgba16ww2t",  "rgba16sint",   "rgba16snt",   "rgba16rrint",
-        "rgba1Gsint",    "rgba16uFFnt",  "g16uEnt",      "rgb16rrint",  "rgba16uint",
-        "gba16uit",      "rXa1DuiJJt",   "rgauint",      "rga32klot",   "rgb32float",
-        "rgJa32flot",    "rgba32float",  "rgba32fcoat",  "rgba32floOt", "__gttavv2fKKoat",
-        "rg5a32xxnt",    "__ba3sqqFt",   "rgbqq2sint",   "rgba32sint",  "33ba32s66nt",
-        "rtt6a3QQooint", "r66ba3sint",   "xba32zzinO6",  "ryyba32uint", "rbZ32HinZ",
-        "rgba32uint",    "rgba3u4WWnq",  "rgba32uOOt",   "oogba2Yin",   "gba8si",
-        "rgba8inF",      "rgba8wnt",     "rgba8sint",    "Gb8Kinff",    "KKgqa8sint",
-        "rgbammsi3t",    "rgba8snom",    "rqba8norm",    "rgbabbsnor",  "rgba8snorm",
-        "rba8siorm",     "qgba8snoOm",   "rgba8snoTTvv", "rgbaFFuint",  "rgQa00uiP",
-        "rgPa8uint",     "rgba8uint",    "rgssa77unt",   "Cgbbb8uiRRt", "rgba8uinXX",
-        "CqgbaOOunorm",  "rgbu8usrL",    "rgba8Xnorm",   "rgba8unorm",  "rgba8unrm",
-        "ba8uqqor",      "rgba8unor22",
+        "bgraunccrm",     "blranr3",      "bVra8unorm",   "bgra8unorm",   "bgra1unorm",
+        "bgrJqqnorm",     "bgr7ll8unorm", "qq32lppHat",   "c2fov",        "r32Goat",
+        "r32float",       "r3viiloat",    "r3WWflo8t",    "rxxfMoat",     "rXsingg",
+        "3siXt",          "r32s3nt",      "r32sint",      "E32sint",      "rPTTsint",
+        "r32sidxx",       "r442uint",     "r3SSuiVVt",    "R32R22t",      "r32uint",
+        "rFui9t",         "r32int",       "VOORRHnt",     "rgy2foat",     "l77nnrr2floGt",
+        "rg42fl00at",     "rg32float",    "rgoofat",      "rgzzflot",     "g11p2fliia",
+        "XXg32sint",      "rII39955nnnt", "aagHH2sinYSS", "rg32sint",     "rkk3it",
+        "gj3sRRn",        "r3bsnt",       "rg32jint",     "rg32unt",      "rgqint",
+        "rg32uint",       "rg32inNN",     "g3vvint",      "rg2uQQnt",     "rga16floft",
+        "rgja16float",    "rgNNww16f2oa", "rgba16float",  "rgba16flot",   "rgba16rrloat",
+        "rgGa16float",    "rgba16sFFnt",  "g16sEnt",      "rgb16rrint",   "rgba16sint",
+        "gba16sit",       "rXa1DsiJJt",   "rgasint",      "rg111kin",     "rgb16uint",
+        "rgJa16uit",      "rgba16uint",   "rgca16uint",   "rgba16Oint",   "KKgba__v6uintt",
+        "rgb832fxx5t",    "rgbaqq__lat",  "rgba32qloat",  "rgba32float",  "33gbO2floa66",
+        "rgboott6QQloat", "66ba32float",  "xba32zzinO6",  "ryyba32sint",  "rbZ32HinZ",
+        "rgba32sint",     "rgba3s4WWnq",  "rgba32sOOt",   "oogba2Yin",    "ga32unt",
+        "Fga32uint",      "rgb32uinw",    "rgba32uint",   "rgGf32uit",    "rgbaqKKuint",
+        "rFba32ummnt",    "rgba8snt",     "rgq8sint",     "rbbba8bin",    "rgba8sint",
+        "rgbisint",       "rgq8sinOO",    "rgbaTTvvint",  "rgFFa8snorm",  "rg00QsnPrm",
+        "rgbaPsnorm",     "rgba8snorm",   "rgb77ssnorm",  "rgba8snbbRRC", "rgbXX8snorm",
+        "qgCCOO8iOOt",    "rsauuinL",     "rgXa8uint",    "rgba8uint",    "rgba8int",
+        "rgbunqq",        "rg22a8uint",   "rybXX0nzzrm",  "rgVVa8iorP",   "rbaCunnnrm",
+        "rgba8unorm",     "ba8unoqqHHA",  "rga8unorm",    "rgfa8uKKo",
     };
     for (auto _ : state) {
         for (auto& str : kStrings) {
diff --git a/src/tint/ast/texel_format_test.cc b/src/tint/ast/texel_format_test.cc
index d257d5e..2caee4a 100644
--- a/src/tint/ast/texel_format_test.cc
+++ b/src/tint/ast/texel_format_test.cc
@@ -42,41 +42,44 @@
 }
 
 static constexpr Case kValidCases[] = {
-    {"r32float", TexelFormat::kR32Float},       {"r32sint", TexelFormat::kR32Sint},
-    {"r32uint", TexelFormat::kR32Uint},         {"rg32float", TexelFormat::kRg32Float},
-    {"rg32sint", TexelFormat::kRg32Sint},       {"rg32uint", TexelFormat::kRg32Uint},
-    {"rgba16float", TexelFormat::kRgba16Float}, {"rgba16sint", TexelFormat::kRgba16Sint},
-    {"rgba16uint", TexelFormat::kRgba16Uint},   {"rgba32float", TexelFormat::kRgba32Float},
-    {"rgba32sint", TexelFormat::kRgba32Sint},   {"rgba32uint", TexelFormat::kRgba32Uint},
-    {"rgba8sint", TexelFormat::kRgba8Sint},     {"rgba8snorm", TexelFormat::kRgba8Snorm},
-    {"rgba8uint", TexelFormat::kRgba8Uint},     {"rgba8unorm", TexelFormat::kRgba8Unorm},
+    {"bgra8unorm", TexelFormat::kBgra8Unorm},   {"r32float", TexelFormat::kR32Float},
+    {"r32sint", TexelFormat::kR32Sint},         {"r32uint", TexelFormat::kR32Uint},
+    {"rg32float", TexelFormat::kRg32Float},     {"rg32sint", TexelFormat::kRg32Sint},
+    {"rg32uint", TexelFormat::kRg32Uint},       {"rgba16float", TexelFormat::kRgba16Float},
+    {"rgba16sint", TexelFormat::kRgba16Sint},   {"rgba16uint", TexelFormat::kRgba16Uint},
+    {"rgba32float", TexelFormat::kRgba32Float}, {"rgba32sint", TexelFormat::kRgba32Sint},
+    {"rgba32uint", TexelFormat::kRgba32Uint},   {"rgba8sint", TexelFormat::kRgba8Sint},
+    {"rgba8snorm", TexelFormat::kRgba8Snorm},   {"rgba8uint", TexelFormat::kRgba8Uint},
+    {"rgba8unorm", TexelFormat::kRgba8Unorm},
 };
 
 static constexpr Case kInvalidCases[] = {
-    {"rcc2flot", TexelFormat::kUndefined},       {"3flo3", TexelFormat::kUndefined},
-    {"r32flVat", TexelFormat::kUndefined},       {"r32s1nt", TexelFormat::kUndefined},
-    {"rq2Jint", TexelFormat::kUndefined},        {"r32sin7ll", TexelFormat::kUndefined},
-    {"ppqq2unHH", TexelFormat::kUndefined},      {"r3cv", TexelFormat::kUndefined},
-    {"b2uiGt", TexelFormat::kUndefined},         {"rgvi2float", TexelFormat::kUndefined},
-    {"rg328WWoat", TexelFormat::kUndefined},     {"rg32lxxMt", TexelFormat::kUndefined},
-    {"rgXggsnt", TexelFormat::kUndefined},       {"rgXsnu", TexelFormat::kUndefined},
-    {"rg32s3nt", TexelFormat::kUndefined},       {"rg3Euint", TexelFormat::kUndefined},
-    {"PP32TTint", TexelFormat::kUndefined},      {"xxg32ddnt", TexelFormat::kUndefined},
-    {"rgba446float", TexelFormat::kUndefined},   {"SSVVba16float", TexelFormat::kUndefined},
-    {"rgbRR6float", TexelFormat::kUndefined},    {"rga16Fint", TexelFormat::kUndefined},
-    {"rgb16sint", TexelFormat::kUndefined},      {"ORVHa16sint", TexelFormat::kUndefined},
-    {"ryba1uint", TexelFormat::kUndefined},      {"r77ba1nnullrrt", TexelFormat::kUndefined},
-    {"rgb4006uint", TexelFormat::kUndefined},    {"rboofloat", TexelFormat::kUndefined},
-    {"rgbaz2loat", TexelFormat::kUndefined},     {"ppga3ii1floa", TexelFormat::kUndefined},
-    {"XXgba32sint", TexelFormat::kUndefined},    {"IIgb9932nni55t", TexelFormat::kUndefined},
-    {"rYbaSSrrsiHHat", TexelFormat::kUndefined}, {"rbkk2Hit", TexelFormat::kUndefined},
-    {"jgba3ugRR", TexelFormat::kUndefined},      {"rgbab2ui", TexelFormat::kUndefined},
-    {"rgba8sijt", TexelFormat::kUndefined},      {"rba8sint", TexelFormat::kUndefined},
-    {"rba8sqt", TexelFormat::kUndefined},        {"rgba8NNnom", TexelFormat::kUndefined},
-    {"rga8vvorm", TexelFormat::kUndefined},      {"rgba8snorQ", TexelFormat::kUndefined},
-    {"rgbauirf", TexelFormat::kUndefined},       {"rgbajuint", TexelFormat::kUndefined},
-    {"wNNgbauin2", TexelFormat::kUndefined},     {"rgba8unrm", TexelFormat::kUndefined},
-    {"rgba8urrorm", TexelFormat::kUndefined},    {"rgba8Gnorm", TexelFormat::kUndefined},
+    {"bgraunccrm", TexelFormat::kUndefined},      {"blranr3", TexelFormat::kUndefined},
+    {"bVra8unorm", TexelFormat::kUndefined},      {"132float", TexelFormat::kUndefined},
+    {"32Jlqqat", TexelFormat::kUndefined},        {"ll3277loat", TexelFormat::kUndefined},
+    {"ppqq2snHH", TexelFormat::kUndefined},       {"r3cv", TexelFormat::kUndefined},
+    {"b2siGt", TexelFormat::kUndefined},          {"r32uiivt", TexelFormat::kUndefined},
+    {"8WW2uint", TexelFormat::kUndefined},        {"rxxuint", TexelFormat::kUndefined},
+    {"rX2flggat", TexelFormat::kUndefined},       {"rg3XVut", TexelFormat::kUndefined},
+    {"3g32float", TexelFormat::kUndefined},       {"rg3Esint", TexelFormat::kUndefined},
+    {"PP32TTint", TexelFormat::kUndefined},       {"xxg32ddnt", TexelFormat::kUndefined},
+    {"44g32uint", TexelFormat::kUndefined},       {"rSS32uinVV", TexelFormat::kUndefined},
+    {"R322Rint", TexelFormat::kUndefined},        {"rgba16fF9a", TexelFormat::kUndefined},
+    {"rgba16floa", TexelFormat::kUndefined},      {"rOObVR16floH", TexelFormat::kUndefined},
+    {"ryba1sint", TexelFormat::kUndefined},       {"r77ba1nnsllrrt", TexelFormat::kUndefined},
+    {"rgb4006sint", TexelFormat::kUndefined},     {"rb1uioot", TexelFormat::kUndefined},
+    {"rga1uzznt", TexelFormat::kUndefined},       {"r11b1uppiit", TexelFormat::kUndefined},
+    {"rgba32fXXoat", TexelFormat::kUndefined},    {"rgbII99355float", TexelFormat::kUndefined},
+    {"rgbaa32fSSrHHYt", TexelFormat::kUndefined}, {"rbkk2Hit", TexelFormat::kUndefined},
+    {"jgba3sgRR", TexelFormat::kUndefined},       {"rgbab2si", TexelFormat::kUndefined},
+    {"rgba32jint", TexelFormat::kUndefined},      {"rba32uint", TexelFormat::kUndefined},
+    {"rgba2uqn", TexelFormat::kUndefined},        {"rbaNNsint", TexelFormat::kUndefined},
+    {"rga8invv", TexelFormat::kUndefined},        {"gba8sQQnt", TexelFormat::kUndefined},
+    {"rgbsnrrff", TexelFormat::kUndefined},       {"rgba8snojm", TexelFormat::kUndefined},
+    {"NNgba8sww2m", TexelFormat::kUndefined},     {"rgba8uit", TexelFormat::kUndefined},
+    {"rrgba8uint", TexelFormat::kUndefined},      {"rgba8uiGt", TexelFormat::kUndefined},
+    {"rgba8unFFrm", TexelFormat::kUndefined},     {"g8unErm", TexelFormat::kUndefined},
+    {"rgb8urrorm", TexelFormat::kUndefined},
 };
 
 using TexelFormatParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index fd67617..a30a133 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -335,6 +335,8 @@
             return "R32Sint";
         case tint::inspector::ResourceBinding::TexelFormat::kR32Float:
             return "R32Float";
+        case tint::inspector::ResourceBinding::TexelFormat::kBgra8Unorm:
+            return "Bgra8Unorm";
         case tint::inspector::ResourceBinding::TexelFormat::kRgba8Unorm:
             return "Rgba8Unorm";
         case tint::inspector::ResourceBinding::TexelFormat::kRgba8Snorm:
diff --git a/src/tint/inspector/resource_binding.cc b/src/tint/inspector/resource_binding.cc
index 4fca85e..4dd26e0 100644
--- a/src/tint/inspector/resource_binding.cc
+++ b/src/tint/inspector/resource_binding.cc
@@ -72,6 +72,8 @@
 ResourceBinding::TexelFormat TypeTexelFormatToResourceBindingTexelFormat(
     const ast::TexelFormat& image_format) {
     switch (image_format) {
+        case ast::TexelFormat::kBgra8Unorm:
+            return ResourceBinding::TexelFormat::kBgra8Unorm;
         case ast::TexelFormat::kR32Uint:
             return ResourceBinding::TexelFormat::kR32Uint;
         case ast::TexelFormat::kR32Sint:
diff --git a/src/tint/inspector/resource_binding.h b/src/tint/inspector/resource_binding.h
index 76b5024..ef22578 100644
--- a/src/tint/inspector/resource_binding.h
+++ b/src/tint/inspector/resource_binding.h
@@ -51,6 +51,7 @@
     enum class TexelFormat {
         kNone = -1,
 
+        kBgra8Unorm,
         kRgba8Unorm,
         kRgba8Snorm,
         kRgba8Uint,
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index c8ff511..08dc366 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -79,6 +79,7 @@
 
 // https://gpuweb.github.io/gpuweb/wgsl/#texel-formats
 enum texel_format {
+  bgra8unorm
   rgba8unorm
   rgba8snorm
   rgba8uint
@@ -244,7 +245,8 @@
 
 // https://gpuweb.github.io/gpuweb/wgsl/#texel-formats
 match f32_texel_format
-  : texel_format.rgba8unorm
+  : texel_format.bgra8unorm
+  | texel_format.rgba8unorm
   | texel_format.rgba8snorm
   | texel_format.rgba16float
   | texel_format.r32float
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index 822be9b..ff077ab8 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -681,7 +681,7 @@
 TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingSubtype) {
     EXPECT("var x : texture_storage_2d<>;",
            R"(test.wgsl:1:28 error: expected texel format for storage texture type
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
 var x : texture_storage_2d<>;
                            ^
 )");
@@ -690,7 +690,7 @@
 TEST_F(ParserImplErrorTest, GlobalDeclStorageTextureMissingInvalidSubtype) {
     EXPECT("var x : texture_storage_2d<1>;",
            R"(test.wgsl:1:28 error: expected texel format for storage texture type
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm'
 var x : texture_storage_2d<1>;
                            ^
 )");
diff --git a/src/tint/reader/wgsl/parser_impl_texel_format_test.cc b/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
index 1697359..8551032 100644
--- a/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
@@ -23,7 +23,7 @@
     EXPECT_TRUE(t.errored);
     EXPECT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), R"(1:1: expected texel format for test
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
 }
 
 TEST_F(ParserImplTest, TexelFormat_R32Uint) {
diff --git a/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc b/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
index 47ea247..01a4241 100644
--- a/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
@@ -219,7 +219,7 @@
     EXPECT_FALSE(t.matched);
     EXPECT_TRUE(t.errored);
     EXPECT_EQ(p->error(), R"(1:20: expected texel format for storage texture type
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidTypeSuggest) {
@@ -230,7 +230,7 @@
     EXPECT_TRUE(t.errored);
     EXPECT_EQ(p->error(),
               R"(1:20: expected texel format for storage texture type. Did you mean 'rg32float'?
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidAccess) {
@@ -251,7 +251,7 @@
     EXPECT_FALSE(t.matched);
     EXPECT_TRUE(t.errored);
     EXPECT_EQ(p->error(), R"(1:20: expected texel format for storage texture type
-Possible values: 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
+Possible values: 'bgra8unorm', 'r32float', 'r32sint', 'r32uint', 'rg32float', 'rg32sint', 'rg32uint', 'rgba16float', 'rgba16sint', 'rgba16uint', 'rgba32float', 'rgba32sint', 'rgba32uint', 'rgba8sint', 'rgba8snorm', 'rgba8uint', 'rgba8unorm')");
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_MissingLessThan) {
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index b13934a..a8351f5 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -2378,6 +2378,7 @@
 
 Number F32TexelFormat::Match(MatchState&, Number number) const {
   switch (static_cast<TexelFormat>(number.Value())) {
+    case TexelFormat::kBgra8Unorm:
     case TexelFormat::kRgba8Unorm:
     case TexelFormat::kRgba8Snorm:
     case TexelFormat::kRgba16Float:
@@ -2391,7 +2392,7 @@
 }
 
 std::string F32TexelFormat::String(MatchState*) const {
-  return "rgba8unorm, rgba8snorm, rgba16float, r32float, rg32float or rgba32float";
+  return "bgra8unorm, rgba8unorm, rgba8snorm, rgba16float, r32float, rg32float or rgba32float";
 }
 
 /// EnumMatcher for 'match i32_texel_format'
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index c3c9119..ebd40b0 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -1126,7 +1126,8 @@
     bool is_valid;
 };
 
-static constexpr FormatParams format_cases[] = {FormatParams{ast::TexelFormat::kR32Float, true},
+static constexpr FormatParams format_cases[] = {FormatParams{ast::TexelFormat::kBgra8Unorm, true},
+                                                FormatParams{ast::TexelFormat::kR32Float, true},
                                                 FormatParams{ast::TexelFormat::kR32Sint, true},
                                                 FormatParams{ast::TexelFormat::kR32Uint, true},
                                                 FormatParams{ast::TexelFormat::kRg32Float, true},
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 6c05df2..c25129a 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -98,6 +98,7 @@
 
 bool IsValidStorageTextureTexelFormat(ast::TexelFormat format) {
     switch (format) {
+        case ast::TexelFormat::kBgra8Unorm:
         case ast::TexelFormat::kR32Uint:
         case ast::TexelFormat::kR32Sint:
         case ast::TexelFormat::kR32Float:
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 2bab400..dbd6f6e 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -833,160 +833,206 @@
 
     bool made_changes = false;
     for (auto* node : src->ASTNodes().Objects()) {
-        auto* expr = src->Sem().Get<sem::Expression>(node);
-        if (!expr || expr->Stage() == sem::EvaluationStage::kConstant ||
-            expr->Stage() == sem::EvaluationStage::kNotEvaluated) {
-            continue;  // Don't polyfill @const expressions
-        }
-
-        if (auto* call = expr->As<sem::Call>()) {
-            auto* builtin = call->Target()->As<sem::Builtin>();
-            if (!builtin) {
-                continue;
-            }
-            Symbol fn;
-            switch (builtin->Type()) {
-                case sem::BuiltinType::kAcosh:
-                    if (polyfill.acosh != Level::kNone) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.acosh(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kAsinh:
-                    if (polyfill.asinh) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.asinh(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kAtanh:
-                    if (polyfill.atanh != Level::kNone) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.atanh(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kClamp:
-                    if (polyfill.clamp_int) {
-                        auto& sig = builtin->Signature();
-                        if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) {
+        Switch(
+            node,
+            [&](const ast::CallExpression* expr) {
+                auto* call = src->Sem().Get(expr)->UnwrapMaterialize()->As<sem::Call>();
+                if (!call || call->Stage() == sem::EvaluationStage::kConstant ||
+                    call->Stage() == sem::EvaluationStage::kNotEvaluated) {
+                    return;  // Don't polyfill @const expressions
+                }
+                auto* builtin = call->Target()->As<sem::Builtin>();
+                if (!builtin) {
+                    return;
+                }
+                Symbol fn;
+                switch (builtin->Type()) {
+                    case sem::BuiltinType::kAcosh:
+                        if (polyfill.acosh != Level::kNone) {
                             fn = builtin_polyfills.GetOrCreate(
-                                builtin, [&] { return s.clampInteger(builtin->ReturnType()); });
+                                builtin, [&] { return s.acosh(builtin->ReturnType()); });
                         }
-                    }
-                    break;
-                case sem::BuiltinType::kCountLeadingZeros:
-                    if (polyfill.count_leading_zeros) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.countLeadingZeros(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kCountTrailingZeros:
-                    if (polyfill.count_trailing_zeros) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.countTrailingZeros(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kExtractBits:
-                    if (polyfill.extract_bits != Level::kNone) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.extractBits(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kFirstLeadingBit:
-                    if (polyfill.first_leading_bit) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kFirstTrailingBit:
-                    if (polyfill.first_trailing_bit) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kInsertBits:
-                    if (polyfill.insert_bits != Level::kNone) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.insertBits(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kSaturate:
-                    if (polyfill.saturate) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.saturate(builtin->ReturnType()); });
-                    }
-                    break;
-                case sem::BuiltinType::kSign:
-                    if (polyfill.sign_int) {
-                        auto* ty = builtin->ReturnType();
-                        if (ty->is_signed_integer_scalar_or_vector()) {
-                            fn = builtin_polyfills.GetOrCreate(builtin,
-                                                               [&] { return s.sign_int(ty); });
+                        break;
+                    case sem::BuiltinType::kAsinh:
+                        if (polyfill.asinh) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.asinh(builtin->ReturnType()); });
                         }
-                    }
-                    break;
-                case sem::BuiltinType::kTextureSampleBaseClampToEdge:
-                    if (polyfill.texture_sample_base_clamp_to_edge_2d_f32) {
-                        auto& sig = builtin->Signature();
-                        auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
-                        if (auto* stex = tex->Type()->As<type::SampledTexture>()) {
-                            if (stex->type()->Is<type::F32>()) {
-                                fn = builtin_polyfills.GetOrCreate(builtin, [&] {
-                                    return s.textureSampleBaseClampToEdge_2d_f32();
-                                });
+                        break;
+                    case sem::BuiltinType::kAtanh:
+                        if (polyfill.atanh != Level::kNone) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.atanh(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kClamp:
+                        if (polyfill.clamp_int) {
+                            auto& sig = builtin->Signature();
+                            if (sig.parameters[0]->Type()->is_integer_scalar_or_vector()) {
+                                fn = builtin_polyfills.GetOrCreate(
+                                    builtin, [&] { return s.clampInteger(builtin->ReturnType()); });
                             }
                         }
-                    }
-                    break;
-                case sem::BuiltinType::kQuantizeToF16:
-                    if (polyfill.quantize_to_vec_f16) {
-                        if (auto* vec = builtin->ReturnType()->As<type::Vector>()) {
-                            fn = builtin_polyfills.GetOrCreate(
-                                builtin, [&] { return s.quantizeToF16(vec); });
+                        break;
+                    case sem::BuiltinType::kCountLeadingZeros:
+                        if (polyfill.count_leading_zeros) {
+                            fn = builtin_polyfills.GetOrCreate(builtin, [&] {
+                                return s.countLeadingZeros(builtin->ReturnType());
+                            });
                         }
-                    }
-                    break;
+                        break;
+                    case sem::BuiltinType::kCountTrailingZeros:
+                        if (polyfill.count_trailing_zeros) {
+                            fn = builtin_polyfills.GetOrCreate(builtin, [&] {
+                                return s.countTrailingZeros(builtin->ReturnType());
+                            });
+                        }
+                        break;
+                    case sem::BuiltinType::kExtractBits:
+                        if (polyfill.extract_bits != Level::kNone) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.extractBits(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kFirstLeadingBit:
+                        if (polyfill.first_leading_bit) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.firstLeadingBit(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kFirstTrailingBit:
+                        if (polyfill.first_trailing_bit) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.firstTrailingBit(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kInsertBits:
+                        if (polyfill.insert_bits != Level::kNone) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.insertBits(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kSaturate:
+                        if (polyfill.saturate) {
+                            fn = builtin_polyfills.GetOrCreate(
+                                builtin, [&] { return s.saturate(builtin->ReturnType()); });
+                        }
+                        break;
+                    case sem::BuiltinType::kSign:
+                        if (polyfill.sign_int) {
+                            auto* ty = builtin->ReturnType();
+                            if (ty->is_signed_integer_scalar_or_vector()) {
+                                fn = builtin_polyfills.GetOrCreate(builtin,
+                                                                   [&] { return s.sign_int(ty); });
+                            }
+                        }
+                        break;
+                    case sem::BuiltinType::kTextureSampleBaseClampToEdge:
+                        if (polyfill.texture_sample_base_clamp_to_edge_2d_f32) {
+                            auto& sig = builtin->Signature();
+                            auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
+                            if (auto* stex = tex->Type()->As<type::SampledTexture>()) {
+                                if (stex->type()->Is<type::F32>()) {
+                                    fn = builtin_polyfills.GetOrCreate(builtin, [&] {
+                                        return s.textureSampleBaseClampToEdge_2d_f32();
+                                    });
+                                }
+                            }
+                        }
+                        break;
+                    case sem::BuiltinType::kTextureStore:
+                        if (polyfill.bgra8unorm) {
+                            auto& sig = builtin->Signature();
+                            auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
+                            if (auto* stex = tex->Type()->As<type::StorageTexture>()) {
+                                if (stex->texel_format() == ast::TexelFormat::kBgra8Unorm) {
+                                    size_t value_idx = static_cast<size_t>(
+                                        sig.IndexOf(sem::ParameterUsage::kValue));
+                                    ctx.Replace(expr, [&ctx, expr, value_idx] {
+                                        utils::Vector<const ast::Expression*, 3> args;
+                                        for (auto* arg : expr->args) {
+                                            arg = ctx.Clone(arg);
+                                            if (args.Length() == value_idx) {  // value
+                                                arg = ctx.dst->MemberAccessor(arg, "bgra");
+                                            }
+                                            args.Push(arg);
+                                        }
+                                        return ctx.dst->Call(
+                                            utils::ToString(sem::BuiltinType::kTextureStore),
+                                            std::move(args));
+                                    });
+                                    made_changes = true;
+                                }
+                            }
+                        }
+                        break;
+                    case sem::BuiltinType::kQuantizeToF16:
+                        if (polyfill.quantize_to_vec_f16) {
+                            if (auto* vec = builtin->ReturnType()->As<type::Vector>()) {
+                                fn = builtin_polyfills.GetOrCreate(
+                                    builtin, [&] { return s.quantizeToF16(vec); });
+                            }
+                        }
+                        break;
 
-                case sem::BuiltinType::kWorkgroupUniformLoad:
-                    if (polyfill.workgroup_uniform_load) {
-                        fn = builtin_polyfills.GetOrCreate(
-                            builtin, [&] { return s.workgroupUniformLoad(builtin->ReturnType()); });
-                    }
-                    break;
+                    case sem::BuiltinType::kWorkgroupUniformLoad:
+                        if (polyfill.workgroup_uniform_load) {
+                            fn = builtin_polyfills.GetOrCreate(builtin, [&] {
+                                return s.workgroupUniformLoad(builtin->ReturnType());
+                            });
+                        }
+                        break;
 
-                default:
-                    break;
-            }
-
-            if (fn.IsValid()) {
-                auto* replacement = b.Call(fn, ctx.Clone(call->Declaration()->args));
-                ctx.Replace(call->Declaration(), replacement);
-                made_changes = true;
-            }
-        } else if (auto* bin_op = node->As<ast::BinaryExpression>()) {
-            switch (bin_op->op) {
-                case ast::BinaryOp::kShiftLeft:
-                case ast::BinaryOp::kShiftRight: {
-                    if (polyfill.bitshift_modulo) {
-                        ctx.Replace(bin_op, [bin_op, &s] { return s.BitshiftModulo(bin_op); });
-                        made_changes = true;
-                    }
-                    break;
+                    default:
+                        break;
                 }
-                case ast::BinaryOp::kDivide:
-                case ast::BinaryOp::kModulo: {
-                    if (polyfill.int_div_mod) {
-                        auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
-                        if (lhs_ty->is_integer_scalar_or_vector()) {
-                            ctx.Replace(bin_op, [bin_op, &s] { return s.IntDivMod(bin_op); });
+
+                if (fn.IsValid()) {
+                    ctx.Replace(call->Declaration(), [&ctx, fn, expr] {
+                        return ctx.dst->Call(fn, ctx.Clone(expr->args));
+                    });
+                    made_changes = true;
+                }
+            },
+            [&](const ast::BinaryExpression* bin_op) {
+                if (auto* sem = src->Sem().Get(bin_op);
+                    !sem || sem->Stage() == sem::EvaluationStage::kConstant ||
+                    sem->Stage() == sem::EvaluationStage::kNotEvaluated) {
+                    return;  // Don't polyfill @const expressions
+                }
+                switch (bin_op->op) {
+                    case ast::BinaryOp::kShiftLeft:
+                    case ast::BinaryOp::kShiftRight: {
+                        if (polyfill.bitshift_modulo) {
+                            ctx.Replace(bin_op, [bin_op, &s] { return s.BitshiftModulo(bin_op); });
                             made_changes = true;
                         }
+                        break;
                     }
-                    break;
+                    case ast::BinaryOp::kDivide:
+                    case ast::BinaryOp::kModulo: {
+                        if (polyfill.int_div_mod) {
+                            auto* lhs_ty = src->TypeOf(bin_op->lhs)->UnwrapRef();
+                            if (lhs_ty->is_integer_scalar_or_vector()) {
+                                ctx.Replace(bin_op, [bin_op, &s] { return s.IntDivMod(bin_op); });
+                                made_changes = true;
+                            }
+                        }
+                        break;
+                    }
+                    default:
+                        break;
                 }
-                default:
-                    break;
-            }
-        }
+            },
+            [&](const ast::StorageTexture* tex) {
+                if (polyfill.bgra8unorm && tex->format == ast::TexelFormat::kBgra8Unorm) {
+                    ctx.Replace(tex, [&ctx, tex] {
+                        return ctx.dst->ty.storage_texture(tex->dim, ast::TexelFormat::kRgba8Unorm,
+                                                           tex->access);
+                    });
+                    made_changes = true;
+                }
+            });
     }
 
     if (!made_changes) {
diff --git a/src/tint/transform/builtin_polyfill.h b/src/tint/transform/builtin_polyfill.h
index a3d5b48..ae5f588 100644
--- a/src/tint/transform/builtin_polyfill.h
+++ b/src/tint/transform/builtin_polyfill.h
@@ -47,6 +47,8 @@
         bool asinh = false;
         /// What level should `atanh` be polyfilled?
         Level atanh = Level::kNone;
+        /// Should storage textures of format 'bgra8unorm' be replaced with 'rgba8unorm'?
+        bool bgra8unorm = false;
         /// Should the RHS of `<<` and `>>` be wrapped in a modulo bit-width of LHS?
         bool bitshift_modulo = false;
         /// Should `clamp()` be polyfilled for integer values (scalar or vector)?
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index aed8d97..2a7f684 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -381,6 +381,138 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// bgra8unorm
+////////////////////////////////////////////////////////////////////////////////
+DataMap polyfillBgra8unorm() {
+    BuiltinPolyfill::Builtins builtins;
+    builtins.bgra8unorm = true;
+    DataMap data;
+    data.Add<BuiltinPolyfill::Config>(builtins);
+    return data;
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBgra8unorm_StorageTextureVar) {
+    auto* src = R"(
+@group(0) @binding(0) var tex : texture_storage_3d<bgra8unorm, write>;
+)";
+
+    EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+    EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBgra8unorm()));
+}
+
+TEST_F(BuiltinPolyfillTest, ShouldRunBgra8unorm_StorageTextureParam) {
+    auto* src = R"(
+fn f(tex : texture_storage_3d<bgra8unorm, write>) {
+}
+)";
+
+    EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
+    EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillBgra8unorm()));
+}
+
+TEST_F(BuiltinPolyfillTest, Bgra8unorm_StorageTextureVar) {
+    auto* src = R"(
+@group(0) @binding(0) var tex : texture_storage_3d<bgra8unorm, write>;
+)";
+
+    auto* expect = R"(
+@group(0) @binding(0) var tex : texture_storage_3d<rgba8unorm, write>;
+)";
+
+    auto got = Run<BuiltinPolyfill>(src, polyfillBgra8unorm());
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Bgra8unorm_StorageTextureParam) {
+    auto* src = R"(
+fn f(tex : texture_storage_3d<bgra8unorm, write>) {
+}
+)";
+
+    auto* expect = R"(
+fn f(tex : texture_storage_3d<rgba8unorm, write>) {
+}
+)";
+
+    auto got = Run<BuiltinPolyfill>(src, polyfillBgra8unorm());
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Bgra8unorm_TextureStore) {
+    auto* src = R"(
+@group(0) @binding(0) var tex : texture_storage_2d<bgra8unorm, write>;
+
+fn f(coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, value);
+}
+)";
+
+    auto* expect = R"(
+@group(0) @binding(0) var tex : texture_storage_2d<rgba8unorm, write>;
+
+fn f(coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, value.bgra);
+}
+)";
+
+    auto got = Run<BuiltinPolyfill>(src, polyfillBgra8unorm());
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Bgra8unorm_TextureStore_Param) {
+    auto* src = R"(
+fn f(tex : texture_storage_2d<bgra8unorm, write>, coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, value);
+}
+)";
+
+    auto* expect = R"(
+fn f(tex : texture_storage_2d<rgba8unorm, write>, coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, value.bgra);
+}
+)";
+
+    auto got = Run<BuiltinPolyfill>(src, polyfillBgra8unorm());
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(BuiltinPolyfillTest, Bgra8unorm_TextureStore_WithAtanh) {
+    auto* src = R"(
+@group(0) @binding(0) var tex : texture_storage_2d<bgra8unorm, write>;
+
+fn f(coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, atanh(value));
+}
+)";
+
+    auto* expect = R"(
+fn tint_atanh(x : vec4<f32>) -> vec4<f32> {
+  return (log(((1 + x) / (1 - x))) * 0.5);
+}
+
+@group(0) @binding(0) var tex : texture_storage_2d<rgba8unorm, write>;
+
+fn f(coords : vec2<i32>, value : vec4<f32>) {
+  textureStore(tex, coords, tint_atanh(value).bgra);
+}
+)";
+
+    BuiltinPolyfill::Builtins builtins;
+    builtins.atanh = BuiltinPolyfill::Level::kFull;
+    builtins.bgra8unorm = true;
+    DataMap data;
+    data.Add<BuiltinPolyfill::Config>(builtins);
+
+    auto got = Run<BuiltinPolyfill>(src, std::move(data));
+
+    EXPECT_EQ(expect, str(got));
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // bitshiftModulo
 ////////////////////////////////////////////////////////////////////////////////
 DataMap polyfillBitshiftModulo() {
diff --git a/src/tint/type/storage_texture.cc b/src/tint/type/storage_texture.cc
index d893767..a47b094 100644
--- a/src/tint/type/storage_texture.cc
+++ b/src/tint/type/storage_texture.cc
@@ -63,6 +63,7 @@
             return type_mgr.Get<I32>();
         }
 
+        case ast::TexelFormat::kBgra8Unorm:
         case ast::TexelFormat::kRgba8Unorm:
         case ast::TexelFormat::kRgba8Snorm:
         case ast::TexelFormat::kR32Float:
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index b5d897d..720423c 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -110,46 +110,6 @@
     return IsAnyOf<ast::BreakStatement>(stmts->Last());
 }
 
-const char* convert_texel_format_to_glsl(const ast::TexelFormat format) {
-    switch (format) {
-        case ast::TexelFormat::kR32Uint:
-            return "r32ui";
-        case ast::TexelFormat::kR32Sint:
-            return "r32i";
-        case ast::TexelFormat::kR32Float:
-            return "r32f";
-        case ast::TexelFormat::kRgba8Unorm:
-            return "rgba8";
-        case ast::TexelFormat::kRgba8Snorm:
-            return "rgba8_snorm";
-        case ast::TexelFormat::kRgba8Uint:
-            return "rgba8ui";
-        case ast::TexelFormat::kRgba8Sint:
-            return "rgba8i";
-        case ast::TexelFormat::kRg32Uint:
-            return "rg32ui";
-        case ast::TexelFormat::kRg32Sint:
-            return "rg32i";
-        case ast::TexelFormat::kRg32Float:
-            return "rg32f";
-        case ast::TexelFormat::kRgba16Uint:
-            return "rgba16ui";
-        case ast::TexelFormat::kRgba16Sint:
-            return "rgba16i";
-        case ast::TexelFormat::kRgba16Float:
-            return "rgba16f";
-        case ast::TexelFormat::kRgba32Uint:
-            return "rgba32ui";
-        case ast::TexelFormat::kRgba32Sint:
-            return "rgba32i";
-        case ast::TexelFormat::kRgba32Float:
-            return "rgba32f";
-        case ast::TexelFormat::kUndefined:
-            return "unknown";
-    }
-    return "unknown";
-}
-
 void PrintF32(std::ostream& out, float value) {
     if (std::isinf(value)) {
         out << "0.0f " << (value >= 0 ? "/* inf */" : "/* -inf */");
@@ -191,6 +151,7 @@
         transform::BuiltinPolyfill::Builtins polyfills;
         polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
         polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
+        polyfills.bgra8unorm = true;
         polyfills.bitshift_modulo = true;
         polyfills.count_leading_zeros = true;
         polyfills.count_trailing_zeros = true;
@@ -2069,7 +2030,65 @@
         return true;
     }
     if (auto* storage = type->As<type::StorageTexture>()) {
-        out << "layout(" << convert_texel_format_to_glsl(storage->texel_format()) << ") ";
+        out << "layout(";
+        switch (storage->texel_format()) {
+            case ast::TexelFormat::kBgra8Unorm:
+                TINT_ICE(Writer, diagnostics_)
+                    << "bgra8unorm should have been polyfilled to rgba8unorm";
+                break;
+            case ast::TexelFormat::kR32Uint:
+                out << "r32ui";
+                break;
+            case ast::TexelFormat::kR32Sint:
+                out << "r32i";
+                break;
+            case ast::TexelFormat::kR32Float:
+                out << "r32f";
+                break;
+            case ast::TexelFormat::kRgba8Unorm:
+                out << "rgba8";
+                break;
+            case ast::TexelFormat::kRgba8Snorm:
+                out << "rgba8_snorm";
+                break;
+            case ast::TexelFormat::kRgba8Uint:
+                out << "rgba8ui";
+                break;
+            case ast::TexelFormat::kRgba8Sint:
+                out << "rgba8i";
+                break;
+            case ast::TexelFormat::kRg32Uint:
+                out << "rg32ui";
+                break;
+            case ast::TexelFormat::kRg32Sint:
+                out << "rg32i";
+                break;
+            case ast::TexelFormat::kRg32Float:
+                out << "rg32f";
+                break;
+            case ast::TexelFormat::kRgba16Uint:
+                out << "rgba16ui";
+                break;
+            case ast::TexelFormat::kRgba16Sint:
+                out << "rgba16i";
+                break;
+            case ast::TexelFormat::kRgba16Float:
+                out << "rgba16f";
+                break;
+            case ast::TexelFormat::kRgba32Uint:
+                out << "rgba32ui";
+                break;
+            case ast::TexelFormat::kRgba32Sint:
+                out << "rgba32i";
+                break;
+            case ast::TexelFormat::kRgba32Float:
+                out << "rgba32f";
+                break;
+            case ast::TexelFormat::kUndefined:
+                TINT_ICE(Writer, diagnostics_) << "invalid texel format";
+                return false;
+        }
+        out << ") ";
     }
     if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(), name)) {
         return false;
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index d9afe1d..3bac389 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -88,6 +88,7 @@
 
 const char* image_format_to_rwtexture_type(ast::TexelFormat image_format) {
     switch (image_format) {
+        case ast::TexelFormat::kBgra8Unorm:
         case ast::TexelFormat::kRgba8Unorm:
         case ast::TexelFormat::kRgba8Snorm:
         case ast::TexelFormat::kRgba16Float:
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index c252f8c..df5a2e3 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -4079,6 +4079,10 @@
 
 SpvImageFormat Builder::convert_texel_format_to_spv(const ast::TexelFormat format) {
     switch (format) {
+        case ast::TexelFormat::kBgra8Unorm:
+            TINT_ICE(Writer, builder_.Diagnostics())
+                << "bgra8unorm should have been polyfilled to rgba8unorm";
+            return SpvImageFormatUnknown;
         case ast::TexelFormat::kR32Uint:
             return SpvImageFormatR32ui;
         case ast::TexelFormat::kR32Sint:
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index 9133703..ef6aa2d 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -57,6 +57,7 @@
         transform::BuiltinPolyfill::Builtins polyfills;
         polyfills.acosh = transform::BuiltinPolyfill::Level::kRangeCheck;
         polyfills.atanh = transform::BuiltinPolyfill::Level::kRangeCheck;
+        polyfills.bgra8unorm = true;
         polyfills.bitshift_modulo = true;
         polyfills.clamp_int = true;
         polyfills.count_leading_zeros = true;
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl
new file mode 100644
index 0000000..59ef53a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_3d<bgra8unorm, write>) -> vec3<u32>
+fn textureDimensions_5b4b10() {
+  var res: vec3<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_5b4b10();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_5b4b10();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..0222f8e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_5b4b10() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint3 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_5b4b10();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_5b4b10();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..0222f8e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_5b4b10() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint3 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_5b4b10();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_5b4b10();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.glsl
new file mode 100644
index 0000000..a572851
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+vec4 vertex_main() {
+  textureDimensions_5b4b10();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+void compute_main() {
+  textureDimensions_5b4b10();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.msl
new file mode 100644
index 0000000..46f9349
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_5b4b10(texture3d<float, access::write> tint_symbol_1) {
+  uint3 res = uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureDimensions_5b4b10(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_5b4b10(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_5b4b10(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.spvasm
new file mode 100644
index 0000000..5b813bd
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_5b4b10 "textureDimensions_5b4b10"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+         %22 = OpConstantNull %v3uint
+         %23 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_5b4b10 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v3uint Function %22
+         %19 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %v3uint %19
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %23
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %29
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.wgsl
new file mode 100644
index 0000000..6805bbe
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/5b4b10.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureDimensions_5b4b10() {
+  var res : vec3<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_5b4b10();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_5b4b10();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl
new file mode 100644
index 0000000..fbc9301
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_1d<bgra8unorm, write>) -> u32
+fn textureDimensions_84f363() {
+  var res: u32 = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_84f363();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_84f363();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_84f363();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..17257f9
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_84f363() {
+  int tint_tmp;
+  arg_0.GetDimensions(tint_tmp);
+  uint res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_84f363();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_84f363();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..17257f9
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_84f363() {
+  int tint_tmp;
+  arg_0.GetDimensions(tint_tmp);
+  uint res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_84f363();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_84f363();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.glsl
new file mode 100644
index 0000000..f5d3ecd
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+vec4 vertex_main() {
+  textureDimensions_84f363();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+void compute_main() {
+  textureDimensions_84f363();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.msl
new file mode 100644
index 0000000..86c6e02
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_84f363(texture1d<float, access::write> tint_symbol_1) {
+  uint res = tint_symbol_1.get_width(0);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureDimensions_84f363(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_84f363(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_84f363(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.spvasm
new file mode 100644
index 0000000..3252410
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 36
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_84f363 "textureDimensions_84f363"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %21 = OpConstantNull %uint
+         %22 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_84f363 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_uint Function %21
+         %18 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %uint %18
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %22
+         %24 = OpLabel
+         %25 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %28
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.wgsl
new file mode 100644
index 0000000..5967fd6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/84f363.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureDimensions_84f363() {
+  var res : u32 = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_84f363();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_84f363();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_84f363();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl
new file mode 100644
index 0000000..c0213af
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_2d_array<bgra8unorm, write>) -> vec2<u32>
+fn textureDimensions_d1b882() {
+  var res: vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_d1b882();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_d1b882();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_d1b882();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..bbf8691
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_d1b882() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint2 res = tint_tmp.xy;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_d1b882();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_d1b882();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..bbf8691
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_d1b882() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint2 res = tint_tmp.xy;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_d1b882();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_d1b882();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.glsl
new file mode 100644
index 0000000..98a46253
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+vec4 vertex_main() {
+  textureDimensions_d1b882();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+void compute_main() {
+  textureDimensions_d1b882();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.msl
new file mode 100644
index 0000000..845a283
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_d1b882(texture2d_array<float, access::write> tint_symbol_1) {
+  uint2 res = uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureDimensions_d1b882(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_d1b882(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_d1b882(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.spvasm
new file mode 100644
index 0000000..a2797a9
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.spvasm
@@ -0,0 +1,78 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 39
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_d1b882 "textureDimensions_d1b882"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %24 = OpConstantNull %v2uint
+         %25 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_d1b882 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v2uint Function %24
+         %21 = OpLoad %11 %arg_0
+         %19 = OpImageQuerySize %v3uint %21
+         %16 = OpVectorShuffle %v2uint %19 %19 0 1
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %25
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %31
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.wgsl
new file mode 100644
index 0000000..aace866
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/d1b882.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureDimensions_d1b882() {
+  var res : vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_d1b882();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_d1b882();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_d1b882();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl
new file mode 100644
index 0000000..3094b6a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_2d<bgra8unorm, write>) -> vec2<u32>
+fn textureDimensions_fbb15a() {
+  var res: vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_fbb15a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_fbb15a();
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..4de727e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_fbb15a() {
+  int2 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y);
+  uint2 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_fbb15a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_fbb15a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..4de727e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_fbb15a() {
+  int2 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y);
+  uint2 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_fbb15a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_fbb15a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.glsl
new file mode 100644
index 0000000..5eeec24
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+vec4 vertex_main() {
+  textureDimensions_fbb15a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+void compute_main() {
+  textureDimensions_fbb15a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.msl
new file mode 100644
index 0000000..ae23db0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_fbb15a(texture2d<float, access::write> tint_symbol_1) {
+  uint2 res = uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureDimensions_fbb15a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_fbb15a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_fbb15a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.spvasm
new file mode 100644
index 0000000..3715140
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_fbb15a "textureDimensions_fbb15a"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %22 = OpConstantNull %v2uint
+         %23 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_fbb15a = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v2uint Function %22
+         %19 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %v2uint %19
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %23
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %29
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.wgsl
new file mode 100644
index 0000000..36b0d9e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureDimensions/fbb15a.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureDimensions_fbb15a() {
+  var res : vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_fbb15a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_fbb15a();
+}
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl
new file mode 100644
index 0000000..d42261f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureNumLayers(texture: texture_storage_2d_array<bgra8unorm, write>) -> u32
+fn textureNumLayers_1f858a() {
+  var res: u32 = textureNumLayers(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureNumLayers_1f858a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureNumLayers_1f858a();
+}
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..d8f7810
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureNumLayers_1f858a() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint res = tint_tmp.z;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureNumLayers_1f858a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureNumLayers_1f858a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..d8f7810
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureNumLayers_1f858a() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint res = tint_tmp.z;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureNumLayers_1f858a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureNumLayers_1f858a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.glsl
new file mode 100644
index 0000000..0eff466
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+vec4 vertex_main() {
+  textureNumLayers_1f858a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+void compute_main() {
+  textureNumLayers_1f858a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.msl
new file mode 100644
index 0000000..688f54e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureNumLayers_1f858a(texture2d_array<float, access::write> tint_symbol_1) {
+  uint res = tint_symbol_1.get_array_size();
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureNumLayers_1f858a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureNumLayers_1f858a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureNumLayers_1f858a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.spvasm
new file mode 100644
index 0000000..9eab744
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.spvasm
@@ -0,0 +1,77 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 38
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureNumLayers_1f858a "textureNumLayers_1f858a"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %23 = OpConstantNull %uint
+         %24 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureNumLayers_1f858a = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_uint Function %23
+         %20 = OpLoad %11 %arg_0
+         %18 = OpImageQuerySize %v3uint %20
+         %16 = OpCompositeExtract %uint %18 2
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.wgsl
new file mode 100644
index 0000000..d08138f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureNumLayers/1f858a.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureNumLayers_1f858a() {
+  var res : u32 = textureNumLayers(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureNumLayers_1f858a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureNumLayers_1f858a();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl
new file mode 100644
index 0000000..75a0f9c
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<u32>, array_index: i32, value: vec4<f32>)
+fn textureStore_27063a() {
+  textureStore(arg_0, vec2<u32>(1u), 1i, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_27063a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_27063a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_27063a();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..64e3e9f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_27063a() {
+  arg_0[uint3((1u).xx, uint(1))] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_27063a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_27063a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_27063a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..64e3e9f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_27063a() {
+  arg_0[uint3((1u).xx, uint(1))] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_27063a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_27063a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_27063a();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.glsl
new file mode 100644
index 0000000..8e6d5af
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), uint(1))), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_27063a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), uint(1))), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_27063a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), uint(1))), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_27063a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.msl
new file mode 100644
index 0000000..9dcbbc9
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_27063a(texture2d_array<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(uint2(1u)), 1);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_27063a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_27063a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_27063a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.spvasm
new file mode 100644
index 0000000..ea4bcb9
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.spvasm
@@ -0,0 +1,80 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 44
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_27063a "textureStore_27063a"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+    %float_1 = OpConstant %float 1
+         %30 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %31 = OpTypeFunction %v4float
+%textureStore_27063a = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+         %23 = OpCompositeExtract %uint %22 0
+         %24 = OpCompositeExtract %uint %22 1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpCompositeConstruct %v3uint %23 %24 %25
+               OpImageWrite %17 %28 %30
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %31
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureStore_27063a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %37
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %39 = OpLabel
+         %40 = OpFunctionCall %void %textureStore_27063a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %42 = OpLabel
+         %43 = OpFunctionCall %void %textureStore_27063a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.wgsl
new file mode 100644
index 0000000..447c4b1
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/27063a.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_27063a() {
+  textureStore(arg_0, vec2<u32>(1u), 1i, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_27063a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_27063a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_27063a();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl
new file mode 100644
index 0000000..2156fa5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d<bgra8unorm, write>, coords: vec2<i32>, value: vec4<f32>)
+fn textureStore_2e4245() {
+  textureStore(arg_0, vec2<i32>(1i), vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_2e4245();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_2e4245();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_2e4245();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c7dd553
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_2e4245() {
+  arg_0[(1).xx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_2e4245();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_2e4245();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c7dd553
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_2e4245() {
+  arg_0[(1).xx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_2e4245();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_2e4245();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.glsl
new file mode 100644
index 0000000..8362a03
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  imageStore(arg_0, ivec2(1), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_2e4245();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  imageStore(arg_0, ivec2(1), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  imageStore(arg_0, ivec2(1), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_2e4245();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.msl
new file mode 100644
index 0000000..85232bf
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_2e4245(texture2d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(int2(1)));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureStore_2e4245(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_2e4245(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_2e4245(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.spvasm
new file mode 100644
index 0000000..4fa753b
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.spvasm
@@ -0,0 +1,73 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_2e4245 "textureStore_2e4245"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %21 = OpConstantComposite %v2int %int_1 %int_1
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %24 = OpTypeFunction %v4float
+%textureStore_2e4245 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %21 %23
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureStore_2e4245
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_2e4245
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureStore_2e4245
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.wgsl
new file mode 100644
index 0000000..ae3343d
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/2e4245.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureStore_2e4245() {
+  textureStore(arg_0, vec2<i32>(1i), vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_2e4245();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_2e4245();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_2e4245();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl
new file mode 100644
index 0000000..ca5609f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<i32>, array_index: i32, value: vec4<f32>)
+fn textureStore_319029() {
+  textureStore(arg_0, vec2<i32>(1i), 1i, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_319029();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_319029();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_319029();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..af6b7c2
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_319029() {
+  arg_0[int3((1).xx, 1)] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_319029();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_319029();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_319029();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..af6b7c2
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_319029() {
+  arg_0[int3((1).xx, 1)] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_319029();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_319029();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_319029();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.glsl
new file mode 100644
index 0000000..a013f36
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  imageStore(arg_0, ivec3(ivec2(1), 1), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_319029();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  imageStore(arg_0, ivec3(ivec2(1), 1), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_319029();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  imageStore(arg_0, ivec3(ivec2(1), 1), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_319029();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.msl
new file mode 100644
index 0000000..85ad3cb
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_319029(texture2d_array<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(int2(1)), 1);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_319029(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_319029(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_319029(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.spvasm
new file mode 100644
index 0000000..b21251d
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.spvasm
@@ -0,0 +1,77 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 41
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_319029 "textureStore_319029"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %22 = OpConstantComposite %v2int %int_1 %int_1
+    %float_1 = OpConstant %float 1
+         %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %28 = OpTypeFunction %v4float
+%textureStore_319029 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+         %23 = OpCompositeExtract %int %22 0
+         %24 = OpCompositeExtract %int %22 1
+         %25 = OpCompositeConstruct %v3int %23 %24 %int_1
+               OpImageWrite %17 %25 %27
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %28
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %textureStore_319029
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %34
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %void %textureStore_319029
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %39 = OpLabel
+         %40 = OpFunctionCall %void %textureStore_319029
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.wgsl
new file mode 100644
index 0000000..23cee71
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/319029.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_319029() {
+  textureStore(arg_0, vec2<i32>(1i), 1i, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_319029();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_319029();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_319029();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl
new file mode 100644
index 0000000..7c96646
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<i32>, array_index: u32, value: vec4<f32>)
+fn textureStore_76affd() {
+  textureStore(arg_0, vec2<i32>(1i), 1u, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_76affd();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_76affd();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_76affd();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..4bf67ae
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_76affd() {
+  arg_0[int3((1).xx, int(1u))] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_76affd();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_76affd();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_76affd();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..4bf67ae
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_76affd() {
+  arg_0[int3((1).xx, int(1u))] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_76affd();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_76affd();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_76affd();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.glsl
new file mode 100644
index 0000000..ed09818
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  imageStore(arg_0, ivec3(ivec2(1), int(1u)), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_76affd();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  imageStore(arg_0, ivec3(ivec2(1), int(1u)), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_76affd();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  imageStore(arg_0, ivec3(ivec2(1), int(1u)), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_76affd();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.msl
new file mode 100644
index 0000000..ff91fd4
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_76affd(texture2d_array<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(int2(1)), 1u);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_76affd(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_76affd(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_76affd(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.spvasm
new file mode 100644
index 0000000..42c9b65
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.spvasm
@@ -0,0 +1,80 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 44
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_76affd "textureStore_76affd"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %22 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+    %float_1 = OpConstant %float 1
+         %30 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %31 = OpTypeFunction %v4float
+%textureStore_76affd = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+         %23 = OpCompositeExtract %int %22 0
+         %24 = OpCompositeExtract %int %22 1
+         %25 = OpBitcast %int %uint_1
+         %28 = OpCompositeConstruct %v3int %23 %24 %25
+               OpImageWrite %17 %28 %30
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %31
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureStore_76affd
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %37
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %39 = OpLabel
+         %40 = OpFunctionCall %void %textureStore_76affd
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %42 = OpLabel
+         %43 = OpFunctionCall %void %textureStore_76affd
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.wgsl
new file mode 100644
index 0000000..df81226
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/76affd.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_76affd() {
+  textureStore(arg_0, vec2<i32>(1i), 1u, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_76affd();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_76affd();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_76affd();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl
new file mode 100644
index 0000000..5d581b6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_3d<bgra8unorm, write>, coords: vec3<u32>, value: vec4<f32>)
+fn textureStore_9aedd3() {
+  textureStore(arg_0, vec3<u32>(1u), vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_9aedd3();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_9aedd3();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_9aedd3();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..bdbc839
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_9aedd3() {
+  arg_0[(1u).xxx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_9aedd3();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_9aedd3();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..bdbc839
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_9aedd3() {
+  arg_0[(1u).xxx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_9aedd3();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_9aedd3();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.glsl
new file mode 100644
index 0000000..d4decdb
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  imageStore(arg_0, ivec3(uvec3(1u)), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_9aedd3();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  imageStore(arg_0, ivec3(uvec3(1u)), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  imageStore(arg_0, ivec3(uvec3(1u)), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_9aedd3();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.msl
new file mode 100644
index 0000000..1dcdfeb
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_9aedd3(texture3d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint3(uint3(1u)));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureStore_9aedd3(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_9aedd3(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_9aedd3(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.spvasm
new file mode 100644
index 0000000..11a4f07
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.spvasm
@@ -0,0 +1,73 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_9aedd3 "textureStore_9aedd3"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %24 = OpTypeFunction %v4float
+%textureStore_9aedd3 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %21 %23
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.wgsl
new file mode 100644
index 0000000..97fb727
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/9aedd3.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureStore_9aedd3() {
+  textureStore(arg_0, vec3<u32>(1u), vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_9aedd3();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_9aedd3();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_9aedd3();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl
new file mode 100644
index 0000000..0494254
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d<bgra8unorm, write>, coords: vec2<u32>, value: vec4<f32>)
+fn textureStore_a165b8() {
+  textureStore(arg_0, vec2<u32>(1u), vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_a165b8();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_a165b8();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_a165b8();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..8f4565f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_a165b8() {
+  arg_0[(1u).xx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_a165b8();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_a165b8();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..8f4565f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_a165b8() {
+  arg_0[(1u).xx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_a165b8();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_a165b8();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.glsl
new file mode 100644
index 0000000..879e186
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  imageStore(arg_0, ivec2(uvec2(1u)), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_a165b8();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  imageStore(arg_0, ivec2(uvec2(1u)), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  imageStore(arg_0, ivec2(uvec2(1u)), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_a165b8();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.msl
new file mode 100644
index 0000000..a1df221
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_a165b8(texture2d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(uint2(1u)));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureStore_a165b8(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_a165b8(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_a165b8(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.spvasm
new file mode 100644
index 0000000..22a5ca5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.spvasm
@@ -0,0 +1,73 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_a165b8 "textureStore_a165b8"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %24 = OpTypeFunction %v4float
+%textureStore_a165b8 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %21 %23
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureStore_a165b8
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_a165b8
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureStore_a165b8
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.wgsl
new file mode 100644
index 0000000..4418cf6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/a165b8.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureStore_a165b8() {
+  textureStore(arg_0, vec2<u32>(1u), vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_a165b8();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_a165b8();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_a165b8();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl
new file mode 100644
index 0000000..e1a17ca
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_3d<bgra8unorm, write>, coords: vec3<i32>, value: vec4<f32>)
+fn textureStore_bedbfc() {
+  textureStore(arg_0, vec3<i32>(1i), vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_bedbfc();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_bedbfc();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_bedbfc();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..3779bb4
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_bedbfc() {
+  arg_0[(1).xxx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_bedbfc();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_bedbfc();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..3779bb4
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_bedbfc() {
+  arg_0[(1).xxx] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_bedbfc();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_bedbfc();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.glsl
new file mode 100644
index 0000000..ca2c613
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  imageStore(arg_0, ivec3(1), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_bedbfc();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  imageStore(arg_0, ivec3(1), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  imageStore(arg_0, ivec3(1), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_bedbfc();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.msl
new file mode 100644
index 0000000..0517df3
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_bedbfc(texture3d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint3(int3(1)));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureStore_bedbfc(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_bedbfc(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_bedbfc(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.spvasm
new file mode 100644
index 0000000..6b28347
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.spvasm
@@ -0,0 +1,73 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_bedbfc "textureStore_bedbfc"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %int_1 = OpConstant %int 1
+         %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %24 = OpTypeFunction %v4float
+%textureStore_bedbfc = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %21 %23
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.wgsl
new file mode 100644
index 0000000..5c4f2b5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/bedbfc.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureStore_bedbfc() {
+  textureStore(arg_0, vec3<i32>(1i), vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_bedbfc();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_bedbfc();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_bedbfc();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl
new file mode 100644
index 0000000..77b1843
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_1d<bgra8unorm, write>, coords: u32, value: vec4<f32>)
+fn textureStore_c9d780() {
+  textureStore(arg_0, 1u, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_c9d780();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_c9d780();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_c9d780();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..2f2dd90
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_c9d780() {
+  arg_0[1u] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_c9d780();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_c9d780();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..2f2dd90
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_c9d780() {
+  arg_0[1u] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_c9d780();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_c9d780();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.glsl
new file mode 100644
index 0000000..9c26224
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  imageStore(arg_0, ivec2(uvec2(1u, 0u)), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_c9d780();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  imageStore(arg_0, ivec2(uvec2(1u, 0u)), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  imageStore(arg_0, ivec2(uvec2(1u, 0u)), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_c9d780();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.msl
new file mode 100644
index 0000000..41a67ee
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_c9d780(texture1d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint(1u));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureStore_c9d780(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_c9d780(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_c9d780(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.spvasm
new file mode 100644
index 0000000..50fe7ea
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.spvasm
@@ -0,0 +1,72 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_c9d780 "textureStore_c9d780"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+    %float_1 = OpConstant %float 1
+         %21 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %22 = OpTypeFunction %v4float
+%textureStore_c9d780 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %uint_1 %21
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %22
+         %24 = OpLabel
+         %25 = OpFunctionCall %void %textureStore_c9d780
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %28
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %textureStore_c9d780
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureStore_c9d780
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.wgsl
new file mode 100644
index 0000000..f7bd4df
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/c9d780.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureStore_c9d780() {
+  textureStore(arg_0, 1u, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_c9d780();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_c9d780();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_c9d780();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl
new file mode 100644
index 0000000..69d5907
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_1d<bgra8unorm, write>, coords: i32, value: vec4<f32>)
+fn textureStore_e0b666() {
+  textureStore(arg_0, 1i, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e0b666();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e0b666();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e0b666();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..4a1c91e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_e0b666() {
+  arg_0[1] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e0b666();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e0b666();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..4a1c91e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_e0b666() {
+  arg_0[1] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e0b666();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e0b666();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.glsl
new file mode 100644
index 0000000..58ddd9d
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  imageStore(arg_0, ivec2(1, 0), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_e0b666();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  imageStore(arg_0, ivec2(1, 0), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  imageStore(arg_0, ivec2(1, 0), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_e0b666();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.msl
new file mode 100644
index 0000000..18b09f0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_e0b666(texture1d<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint(1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureStore_e0b666(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_e0b666(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_e0b666(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.spvasm
new file mode 100644
index 0000000..3684085
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.spvasm
@@ -0,0 +1,72 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_e0b666 "textureStore_e0b666"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+    %float_1 = OpConstant %float 1
+         %21 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %22 = OpTypeFunction %v4float
+%textureStore_e0b666 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+               OpImageWrite %17 %int_1 %21
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %22
+         %24 = OpLabel
+         %25 = OpFunctionCall %void %textureStore_e0b666
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %28
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %textureStore_e0b666
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureStore_e0b666
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.wgsl
new file mode 100644
index 0000000..f03025b
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e0b666.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureStore_e0b666() {
+  textureStore(arg_0, 1i, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e0b666();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e0b666();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e0b666();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl
new file mode 100644
index 0000000..020ff43
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<u32>, array_index: u32, value: vec4<f32>)
+fn textureStore_e38281() {
+  textureStore(arg_0, vec2<u32>(1u), 1u, vec4<f32>(1.f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e38281();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e38281();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e38281();
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..85ecfc5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.dxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_e38281() {
+  arg_0[uint3((1u).xx, 1u)] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e38281();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e38281();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e38281();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..85ecfc5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.fxc.hlsl
@@ -0,0 +1,32 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_e38281() {
+  arg_0[uint3((1u).xx, 1u)] = (1.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e38281();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e38281();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e38281();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.glsl
new file mode 100644
index 0000000..01c89d3
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), 1u)), vec4(1.0f));
+}
+
+vec4 vertex_main() {
+  textureStore_e38281();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), 1u)), vec4(1.0f));
+}
+
+void fragment_main() {
+  textureStore_e38281();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  imageStore(arg_0, ivec3(uvec3(uvec2(1u), 1u)), vec4(1.0f));
+}
+
+void compute_main() {
+  textureStore_e38281();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.msl
new file mode 100644
index 0000000..d3e9a73
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_e38281(texture2d_array<float, access::write> tint_symbol_1) {
+  tint_symbol_1.write(float4(1.0f), uint2(uint2(1u)), 1u);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_e38281(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_e38281(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_e38281(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.spvasm
new file mode 100644
index 0000000..170b5f4
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.spvasm
@@ -0,0 +1,77 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 41
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_e38281 "textureStore_e38281"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+    %float_1 = OpConstant %float 1
+         %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %28 = OpTypeFunction %v4float
+%textureStore_e38281 = OpFunction %void None %12
+         %15 = OpLabel
+         %17 = OpLoad %11 %arg_0
+         %23 = OpCompositeExtract %uint %22 0
+         %24 = OpCompositeExtract %uint %22 1
+         %25 = OpCompositeConstruct %v3uint %23 %24 %uint_1
+               OpImageWrite %17 %25 %27
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %28
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %textureStore_e38281
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %34
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %void %textureStore_e38281
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %39 = OpLabel
+         %40 = OpFunctionCall %void %textureStore_e38281
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.wgsl
new file mode 100644
index 0000000..5b420f5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/textureStore/e38281.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_e38281() {
+  textureStore(arg_0, vec2<u32>(1u), 1u, vec4<f32>(1.0f));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e38281();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e38281();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e38281();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl
new file mode 100644
index 0000000..59ef53a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_3d<bgra8unorm, write>) -> vec3<u32>
+fn textureDimensions_5b4b10() {
+  var res: vec3<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_5b4b10();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_5b4b10();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..0222f8e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_5b4b10() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint3 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_5b4b10();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_5b4b10();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..0222f8e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_5b4b10() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint3 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_5b4b10();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_5b4b10();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.glsl
new file mode 100644
index 0000000..a572851
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+vec4 vertex_main() {
+  textureDimensions_5b4b10();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+void fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureDimensions_5b4b10() {
+  uvec3 res = uvec3(imageSize(arg_0));
+}
+
+void compute_main() {
+  textureDimensions_5b4b10();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.msl
new file mode 100644
index 0000000..46f9349
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_5b4b10(texture3d<float, access::write> tint_symbol_1) {
+  uint3 res = uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureDimensions_5b4b10(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_5b4b10(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_5b4b10(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.spvasm
new file mode 100644
index 0000000..5b813bd
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_5b4b10 "textureDimensions_5b4b10"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+         %22 = OpConstantNull %v3uint
+         %23 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_5b4b10 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v3uint Function %22
+         %19 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %v3uint %19
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %23
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %29
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureDimensions_5b4b10
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.wgsl
new file mode 100644
index 0000000..6805bbe
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/5b4b10.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureDimensions_5b4b10() {
+  var res : vec3<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_5b4b10();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_5b4b10();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_5b4b10();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl
new file mode 100644
index 0000000..fbc9301
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_1d<bgra8unorm, write>) -> u32
+fn textureDimensions_84f363() {
+  var res: u32 = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_84f363();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_84f363();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_84f363();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..17257f9
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_84f363() {
+  int tint_tmp;
+  arg_0.GetDimensions(tint_tmp);
+  uint res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_84f363();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_84f363();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..17257f9
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_84f363() {
+  int tint_tmp;
+  arg_0.GetDimensions(tint_tmp);
+  uint res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_84f363();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_84f363();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.glsl
new file mode 100644
index 0000000..f5d3ecd
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+vec4 vertex_main() {
+  textureDimensions_84f363();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+void fragment_main() {
+  textureDimensions_84f363();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_84f363() {
+  uint res = uvec2(imageSize(arg_0)).x;
+}
+
+void compute_main() {
+  textureDimensions_84f363();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.msl
new file mode 100644
index 0000000..86c6e02
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_84f363(texture1d<float, access::write> tint_symbol_1) {
+  uint res = tint_symbol_1.get_width(0);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureDimensions_84f363(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_84f363(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_84f363(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.spvasm
new file mode 100644
index 0000000..3252410
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 36
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_84f363 "textureDimensions_84f363"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %21 = OpConstantNull %uint
+         %22 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_84f363 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_uint Function %21
+         %18 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %uint %18
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %22
+         %24 = OpLabel
+         %25 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %28
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureDimensions_84f363
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.wgsl
new file mode 100644
index 0000000..5967fd6
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/84f363.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureDimensions_84f363() {
+  var res : u32 = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_84f363();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_84f363();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_84f363();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl
new file mode 100644
index 0000000..c0213af
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_2d_array<bgra8unorm, write>) -> vec2<u32>
+fn textureDimensions_d1b882() {
+  var res: vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_d1b882();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_d1b882();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_d1b882();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..bbf8691
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_d1b882() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint2 res = tint_tmp.xy;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_d1b882();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_d1b882();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..bbf8691
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_d1b882() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint2 res = tint_tmp.xy;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_d1b882();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_d1b882();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.glsl
new file mode 100644
index 0000000..98a46253
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+vec4 vertex_main() {
+  textureDimensions_d1b882();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+void fragment_main() {
+  textureDimensions_d1b882();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureDimensions_d1b882() {
+  uvec2 res = uvec2(imageSize(arg_0).xy);
+}
+
+void compute_main() {
+  textureDimensions_d1b882();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.msl
new file mode 100644
index 0000000..845a283
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_d1b882(texture2d_array<float, access::write> tint_symbol_1) {
+  uint2 res = uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureDimensions_d1b882(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_d1b882(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_d1b882(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.spvasm
new file mode 100644
index 0000000..a2797a9
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.spvasm
@@ -0,0 +1,78 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 39
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_d1b882 "textureDimensions_d1b882"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %24 = OpConstantNull %v2uint
+         %25 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_d1b882 = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v2uint Function %24
+         %21 = OpLoad %11 %arg_0
+         %19 = OpImageQuerySize %v3uint %21
+         %16 = OpVectorShuffle %v2uint %19 %19 0 1
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %25
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %31
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %void %textureDimensions_d1b882
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.wgsl
new file mode 100644
index 0000000..aace866
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/d1b882.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureDimensions_d1b882() {
+  var res : vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_d1b882();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_d1b882();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_d1b882();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl
new file mode 100644
index 0000000..3094b6a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureDimensions(texture: texture_storage_2d<bgra8unorm, write>) -> vec2<u32>
+fn textureDimensions_fbb15a() {
+  var res: vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_fbb15a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_fbb15a();
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..4de727e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_fbb15a() {
+  int2 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y);
+  uint2 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_fbb15a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_fbb15a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..4de727e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureDimensions_fbb15a() {
+  int2 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y);
+  uint2 res = tint_tmp;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureDimensions_fbb15a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureDimensions_fbb15a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.glsl
new file mode 100644
index 0000000..5eeec24
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+vec4 vertex_main() {
+  textureDimensions_fbb15a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+void fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureDimensions_fbb15a() {
+  uvec2 res = uvec2(imageSize(arg_0));
+}
+
+void compute_main() {
+  textureDimensions_fbb15a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.msl
new file mode 100644
index 0000000..ae23db0
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureDimensions_fbb15a(texture2d<float, access::write> tint_symbol_1) {
+  uint2 res = uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height());
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureDimensions_fbb15a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureDimensions_fbb15a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureDimensions_fbb15a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.spvasm
new file mode 100644
index 0000000..3715140
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.spvasm
@@ -0,0 +1,76 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 37
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureDimensions_fbb15a "textureDimensions_fbb15a"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %22 = OpConstantNull %v2uint
+         %23 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureDimensions_fbb15a = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_v2uint Function %22
+         %19 = OpLoad %11 %arg_0
+         %16 = OpImageQuerySize %v2uint %19
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %23
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %29
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %void %textureDimensions_fbb15a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.wgsl
new file mode 100644
index 0000000..36b0d9e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureDimensions/fbb15a.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureDimensions_fbb15a() {
+  var res : vec2<u32> = textureDimensions(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureDimensions_fbb15a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureDimensions_fbb15a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureDimensions_fbb15a();
+}
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl
new file mode 100644
index 0000000..d42261f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureNumLayers(texture: texture_storage_2d_array<bgra8unorm, write>) -> u32
+fn textureNumLayers_1f858a() {
+  var res: u32 = textureNumLayers(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureNumLayers_1f858a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureNumLayers_1f858a();
+}
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..d8f7810
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureNumLayers_1f858a() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint res = tint_tmp.z;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureNumLayers_1f858a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureNumLayers_1f858a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..d8f7810
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureNumLayers_1f858a() {
+  int3 tint_tmp;
+  arg_0.GetDimensions(tint_tmp.x, tint_tmp.y, tint_tmp.z);
+  uint res = tint_tmp.z;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureNumLayers_1f858a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureNumLayers_1f858a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.glsl
new file mode 100644
index 0000000..0eff466
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.glsl
@@ -0,0 +1,52 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+vec4 vertex_main() {
+  textureNumLayers_1f858a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+void fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureNumLayers_1f858a() {
+  uint res = uint(imageSize(arg_0).z);
+}
+
+void compute_main() {
+  textureNumLayers_1f858a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.msl
new file mode 100644
index 0000000..688f54e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureNumLayers_1f858a(texture2d_array<float, access::write> tint_symbol_1) {
+  uint res = tint_symbol_1.get_array_size();
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureNumLayers_1f858a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureNumLayers_1f858a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureNumLayers_1f858a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.spvasm
new file mode 100644
index 0000000..9eab744
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.spvasm
@@ -0,0 +1,77 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 38
+; Schema: 0
+               OpCapability Shader
+               OpCapability ImageQuery
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureNumLayers_1f858a "textureNumLayers_1f858a"
+               OpName %res "res"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %23 = OpConstantNull %uint
+         %24 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%textureNumLayers_1f858a = OpFunction %void None %12
+         %15 = OpLabel
+        %res = OpVariable %_ptr_Function_uint Function %23
+         %20 = OpLoad %11 %arg_0
+         %18 = OpImageQuerySize %v3uint %20
+         %16 = OpCompositeExtract %uint %18 2
+               OpStore %res %16
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %24
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %30
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %36 = OpLabel
+         %37 = OpFunctionCall %void %textureNumLayers_1f858a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.wgsl
new file mode 100644
index 0000000..d08138f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureNumLayers/1f858a.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureNumLayers_1f858a() {
+  var res : u32 = textureNumLayers(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureNumLayers_1f858a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureNumLayers_1f858a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureNumLayers_1f858a();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl
new file mode 100644
index 0000000..d4c6cff
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<u32>, array_index: i32, value: vec4<f32>)
+fn textureStore_27063a() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = 1i;
+  var arg_3 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_27063a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_27063a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_27063a();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..921f8b2
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_27063a() {
+  uint2 arg_1 = (1u).xx;
+  int arg_2 = 1;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[uint3(arg_1, uint(arg_2))] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_27063a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_27063a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_27063a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..921f8b2
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_27063a() {
+  uint2 arg_1 = (1u).xx;
+  int arg_2 = 1;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[uint3(arg_1, uint(arg_2))] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_27063a();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_27063a();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_27063a();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.glsl
new file mode 100644
index 0000000..e94b217
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.glsl
@@ -0,0 +1,61 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  uvec2 arg_1 = uvec2(1u);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, uint(arg_2))), arg_3.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_27063a();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  uvec2 arg_1 = uvec2(1u);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, uint(arg_2))), arg_3.bgra);
+}
+
+void fragment_main() {
+  textureStore_27063a();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_27063a() {
+  uvec2 arg_1 = uvec2(1u);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, uint(arg_2))), arg_3.bgra);
+}
+
+void compute_main() {
+  textureStore_27063a();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.msl
new file mode 100644
index 0000000..54c1bc8
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.msl
@@ -0,0 +1,36 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_27063a(texture2d_array<float, access::write> tint_symbol_1) {
+  uint2 arg_1 = uint2(1u);
+  int arg_2 = 1;
+  float4 arg_3 = float4(1.0f);
+  tint_symbol_1.write(arg_3, uint2(arg_1), arg_2);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_27063a(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_27063a(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_27063a(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.spvasm
new file mode 100644
index 0000000..02ff17d
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.spvasm
@@ -0,0 +1,98 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 56
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_27063a "textureStore_27063a"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %arg_3 "arg_3"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %22 = OpConstantNull %v2uint
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+         %27 = OpConstantNull %int
+    %float_1 = OpConstant %float 1
+         %29 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+     %v3uint = OpTypeVector %uint 3
+         %43 = OpTypeFunction %v4float
+%textureStore_27063a = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2uint Function %22
+      %arg_2 = OpVariable %_ptr_Function_int Function %27
+      %arg_3 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %int_1
+               OpStore %arg_3 %29
+         %33 = OpLoad %11 %arg_0
+         %35 = OpLoad %v2uint %arg_1
+         %36 = OpCompositeExtract %uint %35 0
+         %37 = OpCompositeExtract %uint %35 1
+         %39 = OpLoad %int %arg_2
+         %38 = OpBitcast %uint %39
+         %40 = OpCompositeConstruct %v3uint %36 %37 %38
+         %41 = OpLoad %v4float %arg_3
+         %42 = OpVectorShuffle %v4float %41 %41 2 1 0 3
+               OpImageWrite %33 %40 %42
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %43
+         %45 = OpLabel
+         %46 = OpFunctionCall %void %textureStore_27063a
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %49
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %51 = OpLabel
+         %52 = OpFunctionCall %void %textureStore_27063a
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %54 = OpLabel
+         %55 = OpFunctionCall %void %textureStore_27063a
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.wgsl
new file mode 100644
index 0000000..e2a6f73
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/27063a.wgsl.expected.wgsl
@@ -0,0 +1,24 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_27063a() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = 1i;
+  var arg_3 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_27063a();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_27063a();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_27063a();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl
new file mode 100644
index 0000000..70bf322
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d<bgra8unorm, write>, coords: vec2<i32>, value: vec4<f32>)
+fn textureStore_2e4245() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_2e4245();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_2e4245();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_2e4245();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b6582ed
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_2e4245() {
+  int2 arg_1 = (1).xx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_2e4245();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_2e4245();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b6582ed
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_2e4245() {
+  int2 arg_1 = (1).xx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_2e4245();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_2e4245();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.glsl
new file mode 100644
index 0000000..f5d677b
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  ivec2 arg_1 = ivec2(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_2e4245();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  ivec2 arg_1 = ivec2(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_2e4245();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_2e4245() {
+  ivec2 arg_1 = ivec2(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_2e4245();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.msl
new file mode 100644
index 0000000..bdac7c9
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_2e4245(texture2d<float, access::write> tint_symbol_1) {
+  int2 arg_1 = int2(1);
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint2(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureStore_2e4245(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_2e4245(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_2e4245(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.spvasm
new file mode 100644
index 0000000..43fd631
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.spvasm
@@ -0,0 +1,85 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 45
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_2e4245 "textureStore_2e4245"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+         %22 = OpConstantNull %v2int
+    %float_1 = OpConstant %float 1
+         %24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %32 = OpTypeFunction %v4float
+%textureStore_2e4245 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2int Function %22
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %24
+         %28 = OpLoad %11 %arg_0
+         %29 = OpLoad %v2int %arg_1
+         %30 = OpLoad %v4float %arg_2
+         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
+               OpImageWrite %28 %29 %31
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %32
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureStore_2e4245
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %38
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %40 = OpLabel
+         %41 = OpFunctionCall %void %textureStore_2e4245
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %43 = OpLabel
+         %44 = OpFunctionCall %void %textureStore_2e4245
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.wgsl
new file mode 100644
index 0000000..c191d5e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/2e4245.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureStore_2e4245() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_2e4245();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_2e4245();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_2e4245();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl b/test/tint/builtins/gen/var/textureStore/319029.wgsl
new file mode 100644
index 0000000..0eec371
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<i32>, array_index: i32, value: vec4<f32>)
+fn textureStore_319029() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = 1i;
+  var arg_3 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_319029();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_319029();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_319029();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..6514d61
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_319029() {
+  int2 arg_1 = (1).xx;
+  int arg_2 = 1;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[int3(arg_1, arg_2)] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_319029();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_319029();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_319029();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..6514d61
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_319029() {
+  int2 arg_1 = (1).xx;
+  int arg_2 = 1;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[int3(arg_1, arg_2)] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_319029();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_319029();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_319029();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.glsl
new file mode 100644
index 0000000..58fc772
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.glsl
@@ -0,0 +1,61 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  ivec2 arg_1 = ivec2(1);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, arg_2), arg_3.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_319029();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  ivec2 arg_1 = ivec2(1);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, arg_2), arg_3.bgra);
+}
+
+void fragment_main() {
+  textureStore_319029();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_319029() {
+  ivec2 arg_1 = ivec2(1);
+  int arg_2 = 1;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, arg_2), arg_3.bgra);
+}
+
+void compute_main() {
+  textureStore_319029();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.msl
new file mode 100644
index 0000000..fb8e059
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.msl
@@ -0,0 +1,36 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_319029(texture2d_array<float, access::write> tint_symbol_1) {
+  int2 arg_1 = int2(1);
+  int arg_2 = 1;
+  float4 arg_3 = float4(1.0f);
+  tint_symbol_1.write(arg_3, uint2(arg_1), arg_2);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_319029(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_319029(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_319029(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.spvasm
new file mode 100644
index 0000000..6b35259
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.spvasm
@@ -0,0 +1,95 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 53
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_319029 "textureStore_319029"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %arg_3 "arg_3"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+         %22 = OpConstantNull %v2int
+%_ptr_Function_int = OpTypePointer Function %int
+         %25 = OpConstantNull %int
+    %float_1 = OpConstant %float 1
+         %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+      %v3int = OpTypeVector %int 3
+         %40 = OpTypeFunction %v4float
+%textureStore_319029 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2int Function %22
+      %arg_2 = OpVariable %_ptr_Function_int Function %25
+      %arg_3 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %int_1
+               OpStore %arg_3 %27
+         %31 = OpLoad %11 %arg_0
+         %33 = OpLoad %v2int %arg_1
+         %34 = OpCompositeExtract %int %33 0
+         %35 = OpCompositeExtract %int %33 1
+         %36 = OpLoad %int %arg_2
+         %37 = OpCompositeConstruct %v3int %34 %35 %36
+         %38 = OpLoad %v4float %arg_3
+         %39 = OpVectorShuffle %v4float %38 %38 2 1 0 3
+               OpImageWrite %31 %37 %39
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %40
+         %42 = OpLabel
+         %43 = OpFunctionCall %void %textureStore_319029
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %46
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %48 = OpLabel
+         %49 = OpFunctionCall %void %textureStore_319029
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %51 = OpLabel
+         %52 = OpFunctionCall %void %textureStore_319029
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.wgsl
new file mode 100644
index 0000000..b25c953
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/319029.wgsl.expected.wgsl
@@ -0,0 +1,24 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_319029() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = 1i;
+  var arg_3 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_319029();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_319029();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_319029();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl
new file mode 100644
index 0000000..4ddff3f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<i32>, array_index: u32, value: vec4<f32>)
+fn textureStore_76affd() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = 1u;
+  var arg_3 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_76affd();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_76affd();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_76affd();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c982814
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_76affd() {
+  int2 arg_1 = (1).xx;
+  uint arg_2 = 1u;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[int3(arg_1, int(arg_2))] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_76affd();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_76affd();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_76affd();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c982814
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_76affd() {
+  int2 arg_1 = (1).xx;
+  uint arg_2 = 1u;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[int3(arg_1, int(arg_2))] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_76affd();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_76affd();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_76affd();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.glsl
new file mode 100644
index 0000000..5cbc1bb
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.glsl
@@ -0,0 +1,61 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  ivec2 arg_1 = ivec2(1);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, int(arg_2)), arg_3.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_76affd();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  ivec2 arg_1 = ivec2(1);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, int(arg_2)), arg_3.bgra);
+}
+
+void fragment_main() {
+  textureStore_76affd();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_76affd() {
+  ivec2 arg_1 = ivec2(1);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1, int(arg_2)), arg_3.bgra);
+}
+
+void compute_main() {
+  textureStore_76affd();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.msl
new file mode 100644
index 0000000..9656525
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.msl
@@ -0,0 +1,36 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_76affd(texture2d_array<float, access::write> tint_symbol_1) {
+  int2 arg_1 = int2(1);
+  uint arg_2 = 1u;
+  float4 arg_3 = float4(1.0f);
+  tint_symbol_1.write(arg_3, uint2(arg_1), arg_2);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_76affd(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_76affd(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_76affd(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.spvasm
new file mode 100644
index 0000000..28c7d52
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.spvasm
@@ -0,0 +1,98 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 56
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_76affd "textureStore_76affd"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %arg_3 "arg_3"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
+%_ptr_Function_v2int = OpTypePointer Function %v2int
+         %22 = OpConstantNull %v2int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %27 = OpConstantNull %uint
+    %float_1 = OpConstant %float 1
+         %29 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+      %v3int = OpTypeVector %int 3
+         %43 = OpTypeFunction %v4float
+%textureStore_76affd = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2int Function %22
+      %arg_2 = OpVariable %_ptr_Function_uint Function %27
+      %arg_3 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %uint_1
+               OpStore %arg_3 %29
+         %33 = OpLoad %11 %arg_0
+         %35 = OpLoad %v2int %arg_1
+         %36 = OpCompositeExtract %int %35 0
+         %37 = OpCompositeExtract %int %35 1
+         %39 = OpLoad %uint %arg_2
+         %38 = OpBitcast %int %39
+         %40 = OpCompositeConstruct %v3int %36 %37 %38
+         %41 = OpLoad %v4float %arg_3
+         %42 = OpVectorShuffle %v4float %41 %41 2 1 0 3
+               OpImageWrite %33 %40 %42
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %43
+         %45 = OpLabel
+         %46 = OpFunctionCall %void %textureStore_76affd
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %49
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %51 = OpLabel
+         %52 = OpFunctionCall %void %textureStore_76affd
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %54 = OpLabel
+         %55 = OpFunctionCall %void %textureStore_76affd
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.wgsl
new file mode 100644
index 0000000..0f8fa5a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/76affd.wgsl.expected.wgsl
@@ -0,0 +1,24 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_76affd() {
+  var arg_1 = vec2<i32>(1i);
+  var arg_2 = 1u;
+  var arg_3 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_76affd();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_76affd();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_76affd();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl
new file mode 100644
index 0000000..1da47d1
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_3d<bgra8unorm, write>, coords: vec3<u32>, value: vec4<f32>)
+fn textureStore_9aedd3() {
+  var arg_1 = vec3<u32>(1u);
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_9aedd3();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_9aedd3();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_9aedd3();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..a574647
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_9aedd3() {
+  uint3 arg_1 = (1u).xxx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_9aedd3();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_9aedd3();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..a574647
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_9aedd3() {
+  uint3 arg_1 = (1u).xxx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_9aedd3();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_9aedd3();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.glsl
new file mode 100644
index 0000000..0818848
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  uvec3 arg_1 = uvec3(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1), arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_9aedd3();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  uvec3 arg_1 = uvec3(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1), arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_9aedd3();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_9aedd3() {
+  uvec3 arg_1 = uvec3(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec3(arg_1), arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_9aedd3();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.msl
new file mode 100644
index 0000000..e02f70f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_9aedd3(texture3d<float, access::write> tint_symbol_1) {
+  uint3 arg_1 = uint3(1u);
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint3(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureStore_9aedd3(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_9aedd3(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_9aedd3(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.spvasm
new file mode 100644
index 0000000..e81e58e
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.spvasm
@@ -0,0 +1,85 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 45
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_9aedd3 "textureStore_9aedd3"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+         %22 = OpConstantNull %v3uint
+    %float_1 = OpConstant %float 1
+         %24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %32 = OpTypeFunction %v4float
+%textureStore_9aedd3 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v3uint Function %22
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %24
+         %28 = OpLoad %11 %arg_0
+         %29 = OpLoad %v3uint %arg_1
+         %30 = OpLoad %v4float %arg_2
+         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
+               OpImageWrite %28 %29 %31
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %32
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %38
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %40 = OpLabel
+         %41 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %43 = OpLabel
+         %44 = OpFunctionCall %void %textureStore_9aedd3
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.wgsl
new file mode 100644
index 0000000..651126d
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/9aedd3.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureStore_9aedd3() {
+  var arg_1 = vec3<u32>(1u);
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_9aedd3();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_9aedd3();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_9aedd3();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl
new file mode 100644
index 0000000..d604cd7
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d<bgra8unorm, write>, coords: vec2<u32>, value: vec4<f32>)
+fn textureStore_a165b8() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_a165b8();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_a165b8();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_a165b8();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b7e84ee
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_a165b8() {
+  uint2 arg_1 = (1u).xx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_a165b8();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_a165b8();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b7e84ee
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture2D<float4> arg_0 : register(u0, space1);
+
+void textureStore_a165b8() {
+  uint2 arg_1 = (1u).xx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_a165b8();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_a165b8();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.glsl
new file mode 100644
index 0000000..cd00e25
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  uvec2 arg_1 = uvec2(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1), arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_a165b8();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  uvec2 arg_1 = uvec2(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1), arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_a165b8();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_a165b8() {
+  uvec2 arg_1 = uvec2(1u);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1), arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_a165b8();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.msl
new file mode 100644
index 0000000..d9b7d7f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_a165b8(texture2d<float, access::write> tint_symbol_1) {
+  uint2 arg_1 = uint2(1u);
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint2(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_2) {
+  textureStore_a165b8(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_a165b8(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_a165b8(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.spvasm
new file mode 100644
index 0000000..1d3da9b
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.spvasm
@@ -0,0 +1,85 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 45
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_a165b8 "textureStore_a165b8"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %22 = OpConstantNull %v2uint
+    %float_1 = OpConstant %float 1
+         %24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %32 = OpTypeFunction %v4float
+%textureStore_a165b8 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2uint Function %22
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %24
+         %28 = OpLoad %11 %arg_0
+         %29 = OpLoad %v2uint %arg_1
+         %30 = OpLoad %v4float %arg_2
+         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
+               OpImageWrite %28 %29 %31
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %32
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureStore_a165b8
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %38
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %40 = OpLabel
+         %41 = OpFunctionCall %void %textureStore_a165b8
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %43 = OpLabel
+         %44 = OpFunctionCall %void %textureStore_a165b8
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.wgsl
new file mode 100644
index 0000000..880233b
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/a165b8.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d<bgra8unorm, write>;
+
+fn textureStore_a165b8() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_a165b8();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_a165b8();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_a165b8();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl
new file mode 100644
index 0000000..5beb6bc
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_3d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_3d<bgra8unorm, write>, coords: vec3<i32>, value: vec4<f32>)
+fn textureStore_bedbfc() {
+  var arg_1 = vec3<i32>(1i);
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_bedbfc();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_bedbfc();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_bedbfc();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..8e7b46a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_bedbfc() {
+  int3 arg_1 = (1).xxx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_bedbfc();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_bedbfc();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..8e7b46a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture3D<float4> arg_0 : register(u0, space1);
+
+void textureStore_bedbfc() {
+  int3 arg_1 = (1).xxx;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_bedbfc();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_bedbfc();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.glsl
new file mode 100644
index 0000000..81f7040
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  ivec3 arg_1 = ivec3(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_bedbfc();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  ivec3 arg_1 = ivec3(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_bedbfc();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image3D arg_0;
+void textureStore_bedbfc() {
+  ivec3 arg_1 = ivec3(1);
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, arg_1, arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_bedbfc();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.msl
new file mode 100644
index 0000000..ec97999
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_bedbfc(texture3d<float, access::write> tint_symbol_1) {
+  int3 arg_1 = int3(1);
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint3(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture3d<float, access::write> tint_symbol_2) {
+  textureStore_bedbfc(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture3d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture3d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_bedbfc(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture3d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_bedbfc(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.spvasm
new file mode 100644
index 0000000..1f96712
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.spvasm
@@ -0,0 +1,85 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 45
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_bedbfc "textureStore_bedbfc"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 3D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %int_1 = OpConstant %int 1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+%_ptr_Function_v3int = OpTypePointer Function %v3int
+         %22 = OpConstantNull %v3int
+    %float_1 = OpConstant %float 1
+         %24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %32 = OpTypeFunction %v4float
+%textureStore_bedbfc = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v3int Function %22
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %24
+         %28 = OpLoad %11 %arg_0
+         %29 = OpLoad %v3int %arg_1
+         %30 = OpLoad %v4float %arg_2
+         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
+               OpImageWrite %28 %29 %31
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %32
+         %34 = OpLabel
+         %35 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %38
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %40 = OpLabel
+         %41 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %43 = OpLabel
+         %44 = OpFunctionCall %void %textureStore_bedbfc
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.wgsl
new file mode 100644
index 0000000..11005fc
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/bedbfc.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_3d<bgra8unorm, write>;
+
+fn textureStore_bedbfc() {
+  var arg_1 = vec3<i32>(1i);
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_bedbfc();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_bedbfc();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_bedbfc();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl
new file mode 100644
index 0000000..0b35c40
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_1d<bgra8unorm, write>, coords: u32, value: vec4<f32>)
+fn textureStore_c9d780() {
+  var arg_1 = 1u;
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_c9d780();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_c9d780();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_c9d780();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..ed1c67a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_c9d780() {
+  uint arg_1 = 1u;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_c9d780();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_c9d780();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..ed1c67a
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_c9d780() {
+  uint arg_1 = 1u;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_c9d780();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_c9d780();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.glsl
new file mode 100644
index 0000000..25ce28f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  uint arg_1 = 1u;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(uvec2(arg_1, 0u)), arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_c9d780();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  uint arg_1 = 1u;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(uvec2(arg_1, 0u)), arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_c9d780();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_c9d780() {
+  uint arg_1 = 1u;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(uvec2(arg_1, 0u)), arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_c9d780();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.msl
new file mode 100644
index 0000000..36ba5ff
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_c9d780(texture1d<float, access::write> tint_symbol_1) {
+  uint arg_1 = 1u;
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureStore_c9d780(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_c9d780(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_c9d780(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.spvasm
new file mode 100644
index 0000000..47ab257
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.spvasm
@@ -0,0 +1,84 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 43
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_c9d780 "textureStore_c9d780"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %20 = OpConstantNull %uint
+    %float_1 = OpConstant %float 1
+         %22 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %30 = OpTypeFunction %v4float
+%textureStore_c9d780 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_uint Function %20
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %uint_1
+               OpStore %arg_2 %22
+         %26 = OpLoad %11 %arg_0
+         %27 = OpLoad %uint %arg_1
+         %28 = OpLoad %v4float %arg_2
+         %29 = OpVectorShuffle %v4float %28 %28 2 1 0 3
+               OpImageWrite %26 %27 %29
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %30
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_c9d780
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %36
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %38 = OpLabel
+         %39 = OpFunctionCall %void %textureStore_c9d780
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %41 = OpLabel
+         %42 = OpFunctionCall %void %textureStore_c9d780
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.wgsl
new file mode 100644
index 0000000..f9cf463
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/c9d780.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureStore_c9d780() {
+  var arg_1 = 1u;
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_c9d780();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_c9d780();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_c9d780();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl
new file mode 100644
index 0000000..cd26359
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_1d<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_1d<bgra8unorm, write>, coords: i32, value: vec4<f32>)
+fn textureStore_e0b666() {
+  var arg_1 = 1i;
+  var arg_2 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e0b666();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e0b666();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e0b666();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..1fc59f6
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_e0b666() {
+  int arg_1 = 1;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e0b666();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e0b666();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..1fc59f6
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+RWTexture1D<float4> arg_0 : register(u0, space1);
+
+void textureStore_e0b666() {
+  int arg_1 = 1;
+  float4 arg_2 = (1.0f).xxxx;
+  arg_0[arg_1] = arg_2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e0b666();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e0b666();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.glsl
new file mode 100644
index 0000000..6cee2da
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.glsl
@@ -0,0 +1,58 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  int arg_1 = 1;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1, 0), arg_2.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_e0b666();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  int arg_1 = 1;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1, 0), arg_2.bgra);
+}
+
+void fragment_main() {
+  textureStore_e0b666();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D arg_0;
+void textureStore_e0b666() {
+  int arg_1 = 1;
+  vec4 arg_2 = vec4(1.0f);
+  imageStore(arg_0, ivec2(arg_1, 0), arg_2.bgra);
+}
+
+void compute_main() {
+  textureStore_e0b666();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.msl
new file mode 100644
index 0000000..474423b
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.msl
@@ -0,0 +1,35 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_e0b666(texture1d<float, access::write> tint_symbol_1) {
+  int arg_1 = 1;
+  float4 arg_2 = float4(1.0f);
+  tint_symbol_1.write(arg_2, uint(arg_1));
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture1d<float, access::write> tint_symbol_2) {
+  textureStore_e0b666(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture1d<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture1d<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_e0b666(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture1d<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_e0b666(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.spvasm
new file mode 100644
index 0000000..2ee8650
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.spvasm
@@ -0,0 +1,84 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 43
+; Schema: 0
+               OpCapability Shader
+               OpCapability Image1D
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_e0b666 "textureStore_e0b666"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 1D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+%_ptr_Function_int = OpTypePointer Function %int
+         %20 = OpConstantNull %int
+    %float_1 = OpConstant %float 1
+         %22 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %30 = OpTypeFunction %v4float
+%textureStore_e0b666 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_int Function %20
+      %arg_2 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %int_1
+               OpStore %arg_2 %22
+         %26 = OpLoad %11 %arg_0
+         %27 = OpLoad %int %arg_1
+         %28 = OpLoad %v4float %arg_2
+         %29 = OpVectorShuffle %v4float %28 %28 2 1 0 3
+               OpImageWrite %26 %27 %29
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %30
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %textureStore_e0b666
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %36
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %38 = OpLabel
+         %39 = OpFunctionCall %void %textureStore_e0b666
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %41 = OpLabel
+         %42 = OpFunctionCall %void %textureStore_e0b666
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.wgsl
new file mode 100644
index 0000000..8e0580f
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e0b666.wgsl.expected.wgsl
@@ -0,0 +1,23 @@
+@group(1) @binding(0) var arg_0 : texture_storage_1d<bgra8unorm, write>;
+
+fn textureStore_e0b666() {
+  var arg_1 = 1i;
+  var arg_2 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e0b666();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e0b666();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e0b666();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl
new file mode 100644
index 0000000..936b2dc
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+@group(1) @binding(0) var arg_0: texture_storage_2d_array<bgra8unorm, write>;
+
+// fn textureStore(texture: texture_storage_2d_array<bgra8unorm, write>, coords: vec2<u32>, array_index: u32, value: vec4<f32>)
+fn textureStore_e38281() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = 1u;
+  var arg_3 = vec4<f32>(1.f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e38281();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e38281();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e38281();
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..01438e3
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_e38281() {
+  uint2 arg_1 = (1u).xx;
+  uint arg_2 = 1u;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[uint3(arg_1, arg_2)] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e38281();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e38281();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e38281();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..01438e3
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+RWTexture2DArray<float4> arg_0 : register(u0, space1);
+
+void textureStore_e38281() {
+  uint2 arg_1 = (1u).xx;
+  uint arg_2 = 1u;
+  float4 arg_3 = (1.0f).xxxx;
+  arg_0[uint3(arg_1, arg_2)] = arg_3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  textureStore_e38281();
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+void fragment_main() {
+  textureStore_e38281();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  textureStore_e38281();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.glsl
new file mode 100644
index 0000000..d5f5980
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.glsl
@@ -0,0 +1,61 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  uvec2 arg_1 = uvec2(1u);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, arg_2)), arg_3.bgra);
+}
+
+vec4 vertex_main() {
+  textureStore_e38281();
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
+#version 310 es
+precision mediump float;
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  uvec2 arg_1 = uvec2(1u);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, arg_2)), arg_3.bgra);
+}
+
+void fragment_main() {
+  textureStore_e38281();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2DArray arg_0;
+void textureStore_e38281() {
+  uvec2 arg_1 = uvec2(1u);
+  uint arg_2 = 1u;
+  vec4 arg_3 = vec4(1.0f);
+  imageStore(arg_0, ivec3(uvec3(arg_1, arg_2)), arg_3.bgra);
+}
+
+void compute_main() {
+  textureStore_e38281();
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+  compute_main();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.msl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.msl
new file mode 100644
index 0000000..7f2da16
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.msl
@@ -0,0 +1,36 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void textureStore_e38281(texture2d_array<float, access::write> tint_symbol_1) {
+  uint2 arg_1 = uint2(1u);
+  uint arg_2 = 1u;
+  float4 arg_3 = float4(1.0f);
+  tint_symbol_1.write(arg_3, uint2(arg_1), arg_2);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d_array<float, access::write> tint_symbol_2) {
+  textureStore_e38281(tint_symbol_2);
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d_array<float, access::write> tint_symbol_3 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_3);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main(texture2d_array<float, access::write> tint_symbol_4 [[texture(0)]]) {
+  textureStore_e38281(tint_symbol_4);
+  return;
+}
+
+kernel void compute_main(texture2d_array<float, access::write> tint_symbol_5 [[texture(0)]]) {
+  textureStore_e38281(tint_symbol_5);
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.spvasm
new file mode 100644
index 0000000..2de3603
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.spvasm
@@ -0,0 +1,95 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 53
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
+               OpEntryPoint Fragment %fragment_main "fragment_main"
+               OpEntryPoint GLCompute %compute_main "compute_main"
+               OpExecutionMode %fragment_main OriginUpperLeft
+               OpExecutionMode %compute_main LocalSize 1 1 1
+               OpName %value "value"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %arg_0 "arg_0"
+               OpName %textureStore_e38281 "textureStore_e38281"
+               OpName %arg_1 "arg_1"
+               OpName %arg_2 "arg_2"
+               OpName %arg_3 "arg_3"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpName %fragment_main "fragment_main"
+               OpName %compute_main "compute_main"
+               OpDecorate %value BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %arg_0 NonReadable
+               OpDecorate %arg_0 DescriptorSet 1
+               OpDecorate %arg_0 Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+      %value = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 1 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+      %arg_0 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+       %void = OpTypeVoid
+         %12 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+         %22 = OpConstantNull %v2uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+         %25 = OpConstantNull %uint
+    %float_1 = OpConstant %float 1
+         %27 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+     %v3uint = OpTypeVector %uint 3
+         %40 = OpTypeFunction %v4float
+%textureStore_e38281 = OpFunction %void None %12
+         %15 = OpLabel
+      %arg_1 = OpVariable %_ptr_Function_v2uint Function %22
+      %arg_2 = OpVariable %_ptr_Function_uint Function %25
+      %arg_3 = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %arg_1 %19
+               OpStore %arg_2 %uint_1
+               OpStore %arg_3 %27
+         %31 = OpLoad %11 %arg_0
+         %33 = OpLoad %v2uint %arg_1
+         %34 = OpCompositeExtract %uint %33 0
+         %35 = OpCompositeExtract %uint %33 1
+         %36 = OpLoad %uint %arg_2
+         %37 = OpCompositeConstruct %v3uint %34 %35 %36
+         %38 = OpLoad %v4float %arg_3
+         %39 = OpVectorShuffle %v4float %38 %38 2 1 0 3
+               OpImageWrite %31 %37 %39
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %40
+         %42 = OpLabel
+         %43 = OpFunctionCall %void %textureStore_e38281
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %12
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %46
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %12
+         %48 = OpLabel
+         %49 = OpFunctionCall %void %textureStore_e38281
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %12
+         %51 = OpLabel
+         %52 = OpFunctionCall %void %textureStore_e38281
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.wgsl b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.wgsl
new file mode 100644
index 0000000..8f44a22
--- /dev/null
+++ b/test/tint/builtins/gen/var/textureStore/e38281.wgsl.expected.wgsl
@@ -0,0 +1,24 @@
+@group(1) @binding(0) var arg_0 : texture_storage_2d_array<bgra8unorm, write>;
+
+fn textureStore_e38281() {
+  var arg_1 = vec2<u32>(1u);
+  var arg_2 = 1u;
+  var arg_3 = vec4<f32>(1.0f);
+  textureStore(arg_0, arg_1, arg_2, arg_3);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  textureStore_e38281();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  textureStore_e38281();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  textureStore_e38281();
+}
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl b/test/tint/builtins/textureStore/bgraunorm.wgsl
new file mode 100644
index 0000000..85ea165
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl
@@ -0,0 +1,8 @@
+@group(0) @binding(0) var tex: texture_storage_2d<bgra8unorm, write>;
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  let value = vec4(1f, 2f, 3f, 4f);
+  textureStore(tex, vec2(9, 8), value);
+  return vec4<f32>();
+}
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.dxc.hlsl b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..05405fc
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.dxc.hlsl
@@ -0,0 +1,18 @@
+RWTexture2D<float4> tex : register(u0, space0);
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  const float4 value = float4(1.0f, 2.0f, 3.0f, 4.0f);
+  tex[int2(9, 8)] = value;
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.fxc.hlsl b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..05405fc
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.fxc.hlsl
@@ -0,0 +1,18 @@
+RWTexture2D<float4> tex : register(u0, space0);
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  const float4 value = float4(1.0f, 2.0f, 3.0f, 4.0f);
+  tex[int2(9, 8)] = value;
+  return (0.0f).xxxx;
+}
+
+tint_symbol vertex_main() {
+  const float4 inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = (tint_symbol)0;
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.glsl b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.glsl
new file mode 100644
index 0000000..0dee6cb
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.glsl
@@ -0,0 +1,17 @@
+#version 310 es
+
+layout(rgba8) uniform highp writeonly image2D tex;
+vec4 vertex_main() {
+  vec4 value = vec4(1.0f, 2.0f, 3.0f, 4.0f);
+  imageStore(tex, ivec2(9, 8), value.bgra);
+  return vec4(0.0f);
+}
+
+void main() {
+  gl_PointSize = 1.0;
+  vec4 inner_result = vertex_main();
+  gl_Position = inner_result;
+  gl_Position.y = -(gl_Position.y);
+  gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w);
+  return;
+}
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.msl b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.msl
new file mode 100644
index 0000000..25b3d63
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.msl
@@ -0,0 +1,20 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner(texture2d<float, access::write> tint_symbol_1) {
+  float4 const value = float4(1.0f, 2.0f, 3.0f, 4.0f);
+  tint_symbol_1.write(value, uint2(int2(9, 8)));
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main(texture2d<float, access::write> tint_symbol_2 [[texture(0)]]) {
+  float4 const inner_result = vertex_main_inner(tint_symbol_2);
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.spvasm b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.spvasm
new file mode 100644
index 0000000..e0f2350
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.spvasm
@@ -0,0 +1,56 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 33
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %vertex_main "vertex_main" %value_1 %vertex_point_size
+               OpName %value_1 "value_1"
+               OpName %vertex_point_size "vertex_point_size"
+               OpName %tex "tex"
+               OpName %vertex_main_inner "vertex_main_inner"
+               OpName %vertex_main "vertex_main"
+               OpDecorate %value_1 BuiltIn Position
+               OpDecorate %vertex_point_size BuiltIn PointSize
+               OpDecorate %tex NonReadable
+               OpDecorate %tex DescriptorSet 0
+               OpDecorate %tex Binding 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+          %5 = OpConstantNull %v4float
+    %value_1 = OpVariable %_ptr_Output_v4float Output %5
+%_ptr_Output_float = OpTypePointer Output %float
+          %8 = OpConstantNull %float
+%vertex_point_size = OpVariable %_ptr_Output_float Output %8
+         %11 = OpTypeImage %float 2D 0 0 0 2 Rgba8
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+        %tex = OpVariable %_ptr_UniformConstant_11 UniformConstant
+         %12 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+    %float_3 = OpConstant %float 3
+    %float_4 = OpConstant %float 4
+         %19 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+       %void = OpTypeVoid
+        %int = OpTypeInt 32 1
+      %v2int = OpTypeVector %int 2
+      %int_9 = OpConstant %int 9
+      %int_8 = OpConstant %int 8
+         %27 = OpConstantComposite %v2int %int_9 %int_8
+         %29 = OpTypeFunction %void
+%vertex_main_inner = OpFunction %v4float None %12
+         %14 = OpLabel
+         %22 = OpLoad %11 %tex
+         %28 = OpVectorShuffle %v4float %19 %19 2 1 0 3
+               OpImageWrite %22 %27 %28
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %29
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value_1 %32
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.wgsl b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.wgsl
new file mode 100644
index 0000000..46b1b1c
--- /dev/null
+++ b/test/tint/builtins/textureStore/bgraunorm.wgsl.expected.wgsl
@@ -0,0 +1,8 @@
+@group(0) @binding(0) var tex : texture_storage_2d<bgra8unorm, write>;
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  let value = vec4(1.0f, 2.0f, 3.0f, 4.0f);
+  textureStore(tex, vec2(9, 8), value);
+  return vec4<f32>();
+}