Add const-eval for `exp` and `exp2`.

This CL adds const-eval routines for `exp` and `exp2`.

Bug: tint:1581
Change-Id: I59cc77aee64bfadf6ff10548f27f3d253b68a129
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111322
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index ac4fa4e..7d81bf9 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -460,10 +460,10 @@
 @stage("fragment") fn dpdyCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
 @stage("fragment") fn dpdyFine(f32) -> f32
 @stage("fragment") fn dpdyFine<N: num>(vec<N, f32>) -> vec<N, f32>
-fn exp<T: f32_f16>(T) -> T
-fn exp<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
-fn exp2<T: f32_f16>(T) -> T
-fn exp2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn exp<T: fa_f32_f16>(T) -> T
+@const fn exp<N: num, T: fa_f32_f16>(vec<N, T>) -> vec<N, T>
+@const fn exp2<T: fa_f32_f16>(T) -> T
+@const fn exp2<N: num, T: fa_f32_f16>(vec<N, T>) -> vec<N, T>
 @const fn extractBits<T: iu32>(T, u32, u32) -> T
 @const fn extractBits<N: num, T: iu32>(vec<N, T>, u32, u32) -> vec<N, T>
 fn faceForward<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index c1dabe6..f3cbc9d 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -202,6 +202,15 @@
     return ss.str();
 }
 
+template <typename NumberT>
+std::string OverflowExpErrorMessage(std::string_view base, NumberT value) {
+    std::stringstream ss;
+    ss << std::setprecision(20);
+    ss << base << "^" << value << " cannot be represented as "
+       << "'" << FriendlyName<NumberT>() << "'";
+    return ss.str();
+}
+
 /// @returns the number of consecutive leading bits in `@p e` set to `@p bit_value_to_count`.
 template <typename T>
 std::make_unsigned_t<T> CountLeadingBits(T e, T bit_value_to_count) {
@@ -2037,6 +2046,42 @@
     return r;
 }
 
+ConstEval::Result ConstEval::exp(const sem::Type* ty,
+                                 utils::VectorRef<const sem::Constant*> args,
+                                 const Source& source) {
+    auto transform = [&](const sem::Constant* c0) {
+        auto create = [&](auto e0) -> ImplResult {
+            using NumberT = decltype(e0);
+            auto val = NumberT(std::exp(e0));
+            if (!std::isfinite(val.value)) {
+                AddError(OverflowExpErrorMessage("e", e0), source);
+                return utils::Failure;
+            }
+            return CreateElement(builder, source, c0->Type(), val);
+        };
+        return Dispatch_fa_f32_f16(create, c0);
+    };
+    return TransformElements(builder, ty, transform, args[0]);
+}
+
+ConstEval::Result ConstEval::exp2(const sem::Type* ty,
+                                  utils::VectorRef<const sem::Constant*> args,
+                                  const Source& source) {
+    auto transform = [&](const sem::Constant* c0) {
+        auto create = [&](auto e0) -> ImplResult {
+            using NumberT = decltype(e0);
+            auto val = NumberT(std::exp2(e0));
+            if (!std::isfinite(val.value)) {
+                AddError(OverflowExpErrorMessage("2", e0), source);
+                return utils::Failure;
+            }
+            return CreateElement(builder, source, c0->Type(), val);
+        };
+        return Dispatch_fa_f32_f16(create, c0);
+    };
+    return TransformElements(builder, ty, transform, args[0]);
+}
+
 ConstEval::Result ConstEval::extractBits(const sem::Type* ty,
                                          utils::VectorRef<const sem::Constant*> args,
                                          const Source& source) {
diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h
index f290adb..2f2edc4 100644
--- a/src/tint/resolver/const_eval.h
+++ b/src/tint/resolver/const_eval.h
@@ -556,6 +556,24 @@
                utils::VectorRef<const sem::Constant*> args,
                const Source& source);
 
+    /// exp builtin
+    /// @param ty the expression type
+    /// @param args the input arguments
+    /// @param source the source location
+    /// @return the result value, or null if the value cannot be calculated
+    Result exp(const sem::Type* ty,
+               utils::VectorRef<const sem::Constant*> args,
+               const Source& source);
+
+    /// exp2 builtin
+    /// @param ty the expression type
+    /// @param args the input arguments
+    /// @param source the source location
+    /// @return the result value, or null if the value cannot be calculated
+    Result exp2(const sem::Type* ty,
+                utils::VectorRef<const sem::Constant*> args,
+                const Source& source);
+
     /// extractBits builtin
     /// @param ty the expression type
     /// @param args the input arguments
diff --git a/src/tint/resolver/const_eval_builtin_test.cc b/src/tint/resolver/const_eval_builtin_test.cc
index e7d4574..fe587ff 100644
--- a/src/tint/resolver/const_eval_builtin_test.cc
+++ b/src/tint/resolver/const_eval_builtin_test.cc
@@ -1102,6 +1102,46 @@
                      testing::ValuesIn(DegreesF16Cases<f16>())));
 
 template <typename T>
+std::vector<Case> ExpCases() {
+    auto error_msg = [](auto a) { return "12:34 error: " + OverflowExpErrorMessage("e", a); };
+    return std::vector<Case>{C({T(0)}, T(1)),   //
+                             C({-T(0)}, T(1)),  //
+                             C({T(2)}, T(7.3890562)).FloatComp(),
+                             C({-T(2)}, T(0.13533528)).FloatComp(),  //
+                             C({T::Lowest()}, T(0)),
+
+                             E({T::Highest()}, error_msg(T::Highest()))};
+}
+INSTANTIATE_TEST_SUITE_P(  //
+    Exp,
+    ResolverConstEvalBuiltinTest,
+    testing::Combine(testing::Values(sem::BuiltinType::kExp),
+                     testing::ValuesIn(Concat(ExpCases<AFloat>(),  //
+                                              ExpCases<f32>(),
+                                              ExpCases<f16>()))));
+
+template <typename T>
+std::vector<Case> Exp2Cases() {
+    auto error_msg = [](auto a) { return "12:34 error: " + OverflowExpErrorMessage("2", a); };
+    return std::vector<Case>{
+        C({T(0)}, T(1)),   //
+        C({-T(0)}, T(1)),  //
+        C({T(2)}, T(4.0)),
+        C({-T(2)}, T(0.25)),  //
+        C({T::Lowest()}, T(0)),
+
+        E({T::Highest()}, error_msg(T::Highest())),
+    };
+}
+INSTANTIATE_TEST_SUITE_P(  //
+    Exp2,
+    ResolverConstEvalBuiltinTest,
+    testing::Combine(testing::Values(sem::BuiltinType::kExp2),
+                     testing::ValuesIn(Concat(Exp2Cases<AFloat>(),  //
+                                              Exp2Cases<f32>(),
+                                              Exp2Cases<f16>()))));
+
+template <typename T>
 std::vector<Case> ExtractBitsCases() {
     using UT = Number<std::make_unsigned_t<UnwrapNumber<T>>>;
 
diff --git a/src/tint/resolver/const_eval_test.h b/src/tint/resolver/const_eval_test.h
index bc85542..8975752 100644
--- a/src/tint/resolver/const_eval_test.h
+++ b/src/tint/resolver/const_eval_test.h
@@ -223,7 +223,7 @@
     return ss.str();
 }
 
-/// Returns the overflow error message for converions
+/// Returns the overflow error message for conversions
 template <typename VALUE_TY>
 std::string OverflowErrorMessage(VALUE_TY value, std::string_view target_ty) {
     std::stringstream ss;
@@ -233,6 +233,16 @@
     return ss.str();
 }
 
+/// Returns the overflow error message for exponentiation
+template <typename NumberT>
+std::string OverflowExpErrorMessage(std::string_view base, NumberT value) {
+    std::stringstream ss;
+    ss << std::setprecision(20);
+    ss << base << "^" << value << " cannot be represented as "
+       << "'" << FriendlyName<NumberT>() << "'";
+    return ss.str();
+}
+
 using builder::IsValue;
 using builder::Mat;
 using builder::Val;
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index e21a84b..74f377c 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -12366,48 +12366,48 @@
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[23],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[850],
     /* return matcher indices */ &kMatcherIndices[3],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
-    /* const eval */ nullptr,
+    /* const eval */ &ConstEval::exp,
   },
   {
     /* [338] */
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[23],
     /* template numbers */ &kTemplateNumbers[4],
     /* parameters */ &kParameters[851],
     /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
-    /* const eval */ nullptr,
+    /* const eval */ &ConstEval::exp,
   },
   {
     /* [339] */
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 0,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[23],
     /* template numbers */ &kTemplateNumbers[10],
     /* parameters */ &kParameters[852],
     /* return matcher indices */ &kMatcherIndices[3],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
-    /* const eval */ nullptr,
+    /* const eval */ &ConstEval::exp2,
   },
   {
     /* [340] */
     /* num parameters */ 1,
     /* num template types */ 1,
     /* num template numbers */ 1,
-    /* template types */ &kTemplateTypes[26],
+    /* template types */ &kTemplateTypes[23],
     /* template numbers */ &kTemplateNumbers[4],
     /* parameters */ &kParameters[853],
     /* return matcher indices */ &kMatcherIndices[30],
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
-    /* const eval */ nullptr,
+    /* const eval */ &ConstEval::exp2,
   },
   {
     /* [341] */
@@ -14197,15 +14197,15 @@
   },
   {
     /* [31] */
-    /* fn exp<T : f32_f16>(T) -> T */
-    /* fn exp<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+    /* fn exp<T : fa_f32_f16>(T) -> T */
+    /* fn exp<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[337],
   },
   {
     /* [32] */
-    /* fn exp2<T : f32_f16>(T) -> T */
-    /* fn exp2<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
+    /* fn exp2<T : fa_f32_f16>(T) -> T */
+    /* fn exp2<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
     /* num overloads */ 2,
     /* overloads */ &kOverloads[339],
   },
diff --git a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.dxc.hlsl
index bfdf17d..f3d2a84 100644
--- a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_0f70eb() {
-  float4 res = exp((1.0f).xxxx);
+  float4 res = (2.718281746f).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.fxc.hlsl
index bfdf17d..f3d2a84 100644
--- a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp_0f70eb() {
-  float4 res = exp((1.0f).xxxx);
+  float4 res = (2.718281746f).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.glsl
index aa694a1..d2c6e1a 100644
--- a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp_0f70eb() {
-  vec4 res = exp(vec4(1.0f));
+  vec4 res = vec4(2.718281746f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp_0f70eb() {
-  vec4 res = exp(vec4(1.0f));
+  vec4 res = vec4(2.718281746f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp_0f70eb() {
-  vec4 res = exp(vec4(1.0f));
+  vec4 res = vec4(2.718281746f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.msl
index 51985ab..2a9ee2c 100644
--- a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_0f70eb() {
-  float4 res = exp(float4(1.0f));
+  float4 res = float4(2.718281746f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.spvasm
index 25e78f8..731ff6c 100644
--- a/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/0f70eb.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 32
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
-         %14 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -31,36 +30,36 @@
 %vertex_point_size = OpVariable %_ptr_Output_float Output %8
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
-    %float_1 = OpConstant %float 1
-         %16 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%float_2_71828175 = OpConstant %float 2.71828175
+         %14 = OpConstantComposite %v4float %float_2_71828175 %float_2_71828175 %float_2_71828175 %float_2_71828175
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %19 = OpTypeFunction %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
  %exp_0f70eb = OpFunction %void None %9
          %12 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function %5
-         %13 = OpExtInst %v4float %14 Exp %16
-               OpStore %res %13
+               OpStore %res %14
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %19
-         %21 = OpLabel
-         %22 = OpFunctionCall %void %exp_0f70eb
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp_0f70eb
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %25
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %void %exp_0f70eb
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp_0f70eb
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %30 = OpLabel
-         %31 = OpFunctionCall %void %exp_0f70eb
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_0f70eb
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.dxc.hlsl
index 8a2a30a..d9a9550 100644
--- a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_13806d() {
-  vector<float16_t, 3> res = exp((float16_t(1.0h)).xxx);
+  vector<float16_t, 3> res = (float16_t(2.716796875h)).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.glsl
index 18dca94..9b4e3f4 100644
--- a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_13806d() {
-  f16vec3 res = exp(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.716796875hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp_13806d() {
-  f16vec3 res = exp(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.716796875hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_13806d() {
-  f16vec3 res = exp(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.716796875hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.msl
index 7150692..24409f7 100644
--- a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_13806d() {
-  half3 res = exp(half3(1.0h));
+  half3 res = half3(2.716796875h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.spvasm
index 039b69b..837fc5e 100644
--- a/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/13806d.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v3half = OpTypeVector %half 3
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
+%half_0x1_5bcp_1 = OpConstant %half 0x1.5bcp+1
+         %16 = OpConstantComposite %v3half %half_0x1_5bcp_1 %half_0x1_5bcp_1 %half_0x1_5bcp_1
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-         %21 = OpConstantNull %v3half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v3half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
  %exp_13806d = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v3half Function %21
-         %13 = OpExtInst %v3half %16 Exp %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v3half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp_13806d
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp_13806d
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp_13806d
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_13806d
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp_13806d
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp_13806d
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.dxc.hlsl
index 776ab24..22d7711 100644
--- a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_1951e7() {
-  float2 res = exp((1.0f).xx);
+  float2 res = (2.718281746f).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.fxc.hlsl
index 776ab24..22d7711 100644
--- a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp_1951e7() {
-  float2 res = exp((1.0f).xx);
+  float2 res = (2.718281746f).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.glsl
index f2bbd7c..33980c0 100644
--- a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp_1951e7() {
-  vec2 res = exp(vec2(1.0f));
+  vec2 res = vec2(2.718281746f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp_1951e7() {
-  vec2 res = exp(vec2(1.0f));
+  vec2 res = vec2(2.718281746f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp_1951e7() {
-  vec2 res = exp(vec2(1.0f));
+  vec2 res = vec2(2.718281746f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.msl
index f498a3e..4b3ae55 100644
--- a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_1951e7() {
-  float2 res = exp(float2(1.0f));
+  float2 res = float2(2.718281746f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.spvasm
index adca51e..ecf7ddc 100644
--- a/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/1951e7.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -32,37 +31,37 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
     %v2float = OpTypeVector %float 2
-    %float_1 = OpConstant %float 1
-         %17 = OpConstantComposite %v2float %float_1 %float_1
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v2float %float_2_71828175 %float_2_71828175
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-         %20 = OpConstantNull %v2float
-         %21 = OpTypeFunction %v4float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
  %exp_1951e7 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v2float Function %20
-         %13 = OpExtInst %v2float %15 Exp %17
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %21
-         %23 = OpLabel
-         %24 = OpFunctionCall %void %exp_1951e7
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_1951e7
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %27
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp_1951e7
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_1951e7
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp_1951e7
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_1951e7
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.dxc.hlsl
index a9d2ab8..2fafcbe 100644
--- a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_2e08e2() {
-  vector<float16_t, 2> res = exp((float16_t(1.0h)).xx);
+  vector<float16_t, 2> res = (float16_t(2.716796875h)).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.glsl
index ead6fec..becbb7f 100644
--- a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_2e08e2() {
-  f16vec2 res = exp(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.716796875hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp_2e08e2() {
-  f16vec2 res = exp(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.716796875hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_2e08e2() {
-  f16vec2 res = exp(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.716796875hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.msl
index 5336de7..1b3ef24 100644
--- a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_2e08e2() {
-  half2 res = exp(half2(1.0h));
+  half2 res = half2(2.716796875h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.spvasm
index 25e43eb..d09432d 100644
--- a/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/2e08e2.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v2half = OpTypeVector %half 2
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
+%half_0x1_5bcp_1 = OpConstant %half 0x1.5bcp+1
+         %16 = OpConstantComposite %v2half %half_0x1_5bcp_1 %half_0x1_5bcp_1
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-         %21 = OpConstantNull %v2half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v2half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
  %exp_2e08e2 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v2half Function %21
-         %13 = OpExtInst %v2half %16 Exp %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v2half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp_2e08e2
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp_2e08e2
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp_2e08e2
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_2e08e2
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp_2e08e2
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp_2e08e2
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl
new file mode 100644
index 0000000..4bbe43e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(fa) -> fa
+fn exp_49e4c5() {
+  var res = exp(1.);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_49e4c5();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_49e4c5();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_49e4c5();
+}
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..a370f26
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  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() {
+  exp_49e4c5();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_49e4c5();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..a370f26
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  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() {
+  exp_49e4c5();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_49e4c5();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.glsl
new file mode 100644
index 0000000..304cb4d
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+vec4 vertex_main() {
+  exp_49e4c5();
+  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;
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+void fragment_main() {
+  exp_49e4c5();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+void compute_main() {
+  exp_49e4c5();
+}
+
+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/exp/49e4c5.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.msl
new file mode 100644
index 0000000..94c050b
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_49e4c5();
+  return;
+}
+
+kernel void compute_main() {
+  exp_49e4c5();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.spvasm
new file mode 100644
index 0000000..9cb7981
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %exp_49e4c5 "exp_49e4c5"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+%float_2_71828175 = OpConstant %float 2.71828175
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_49e4c5 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_2_71828175
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp_49e4c5
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp_49e4c5
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_49e4c5
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.wgsl
new file mode 100644
index 0000000..5b0554b
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/49e4c5.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp_49e4c5() {
+  var res = exp(1.0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_49e4c5();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_49e4c5();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_49e4c5();
+}
diff --git a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.dxc.hlsl
index 4083b4d..d0e47ae 100644
--- a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_611a87() {
-  vector<float16_t, 4> res = exp((float16_t(1.0h)).xxxx);
+  vector<float16_t, 4> res = (float16_t(2.716796875h)).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.glsl
index f9ec5fb..640ace7 100644
--- a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_611a87() {
-  f16vec4 res = exp(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.716796875hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp_611a87() {
-  f16vec4 res = exp(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.716796875hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_611a87() {
-  f16vec4 res = exp(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.716796875hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.msl
index 72cfc9e..2cea3b7 100644
--- a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_611a87() {
-  half4 res = exp(half4(1.0h));
+  half4 res = half4(2.716796875h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.spvasm
index 2883d1e..3e3bd45 100644
--- a/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/611a87.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v4half = OpTypeVector %half 4
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
+%half_0x1_5bcp_1 = OpConstant %half 0x1.5bcp+1
+         %16 = OpConstantComposite %v4half %half_0x1_5bcp_1 %half_0x1_5bcp_1 %half_0x1_5bcp_1 %half_0x1_5bcp_1
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-         %21 = OpConstantNull %v4half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v4half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
  %exp_611a87 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v4half Function %21
-         %13 = OpExtInst %v4half %16 Exp %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v4half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp_611a87
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp_611a87
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp_611a87
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_611a87
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp_611a87
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp_611a87
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl b/test/tint/builtins/gen/literal/exp/699629.wgsl
new file mode 100644
index 0000000..b221d3b
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<2, fa>) -> vec<2, fa>
+fn exp_699629() {
+  var res = exp(vec2(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_699629();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_699629();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_699629();
+}
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f19809c
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_699629() {
+  float2 res = (2.718281746f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  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() {
+  exp_699629();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_699629();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f19809c
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_699629() {
+  float2 res = (2.718281746f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  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() {
+  exp_699629();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_699629();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.glsl
new file mode 100644
index 0000000..93856b5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_699629();
+  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;
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+void fragment_main() {
+  exp_699629();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+void compute_main() {
+  exp_699629();
+}
+
+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/exp/699629.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.msl
new file mode 100644
index 0000000..e68e3dd
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_699629() {
+  float2 res = float2(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_699629();
+  return;
+}
+
+kernel void compute_main() {
+  exp_699629();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.spvasm
new file mode 100644
index 0000000..c607906
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp_699629 "exp_699629"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v2float = OpTypeVector %float 2
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v2float %float_2_71828175 %float_2_71828175
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_699629 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_699629
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_699629
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_699629
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.wgsl
new file mode 100644
index 0000000..2fe65e0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/699629.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp_699629() {
+  var res = exp(vec2(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_699629();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_699629();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_699629();
+}
diff --git a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.dxc.hlsl
index 06b4392..5f88788 100644
--- a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.fxc.hlsl
index 06b4392..5f88788 100644
--- a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.glsl
index f5c1b66..882d7aa 100644
--- a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.msl
index a291006..f86564f 100644
--- a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_771fd2() {
-  float res = exp(1.0f);
+  float res = 2.718281746f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.spvasm
index 1d731bd..c2b53f7 100644
--- a/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/771fd2.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 31
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
-         %14 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -31,35 +30,35 @@
 %vertex_point_size = OpVariable %_ptr_Output_float Output %8
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
-    %float_1 = OpConstant %float 1
+%float_2_71828175 = OpConstant %float 2.71828175
 %_ptr_Function_float = OpTypePointer Function %float
-         %18 = OpTypeFunction %v4float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
  %exp_771fd2 = OpFunction %void None %9
          %12 = OpLabel
         %res = OpVariable %_ptr_Function_float Function %8
-         %13 = OpExtInst %float %14 Exp %float_1
-               OpStore %res %13
+               OpStore %res %float_2_71828175
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %18
-         %20 = OpLabel
-         %21 = OpFunctionCall %void %exp_771fd2
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp_771fd2
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %24
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %void %exp_771fd2
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp_771fd2
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp_771fd2
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_771fd2
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl
new file mode 100644
index 0000000..d76164e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<3, fa>) -> vec<3, fa>
+fn exp_bda5bb() {
+  var res = exp(vec3(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_bda5bb();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_bda5bb();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_bda5bb();
+}
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..ea132ce
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_bda5bb() {
+  float3 res = (2.718281746f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  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() {
+  exp_bda5bb();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_bda5bb();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..ea132ce
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_bda5bb() {
+  float3 res = (2.718281746f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  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() {
+  exp_bda5bb();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_bda5bb();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.glsl
new file mode 100644
index 0000000..65cb0f6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_bda5bb();
+  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;
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+void fragment_main() {
+  exp_bda5bb();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+void compute_main() {
+  exp_bda5bb();
+}
+
+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/exp/bda5bb.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.msl
new file mode 100644
index 0000000..46be400
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_bda5bb() {
+  float3 res = float3(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_bda5bb();
+  return;
+}
+
+kernel void compute_main() {
+  exp_bda5bb();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.spvasm
new file mode 100644
index 0000000..018b829
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp_bda5bb "exp_bda5bb"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v3float = OpTypeVector %float 3
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v3float %float_2_71828175 %float_2_71828175 %float_2_71828175
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_bda5bb = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_bda5bb
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_bda5bb
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_bda5bb
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.wgsl
new file mode 100644
index 0000000..b322331
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/bda5bb.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp_bda5bb() {
+  var res = exp(vec3(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_bda5bb();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_bda5bb();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_bda5bb();
+}
diff --git a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.dxc.hlsl
index 5d32e2d..ba22674 100644
--- a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_c18fe9() {
-  float16_t res = exp(float16_t(1.0h));
+  float16_t res = float16_t(2.716796875h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.glsl
index be9113a..a3fe909 100644
--- a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_c18fe9() {
-  float16_t res = exp(1.0hf);
+  float16_t res = 2.716796875hf;
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp_c18fe9() {
-  float16_t res = exp(1.0hf);
+  float16_t res = 2.716796875hf;
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp_c18fe9() {
-  float16_t res = exp(1.0hf);
+  float16_t res = 2.716796875hf;
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.msl
index 120d379..0b563f7 100644
--- a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_c18fe9() {
-  half res = exp(1.0h);
+  half res = 2.716796875h;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.spvasm
index fab791b..6e7d8b2 100644
--- a/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/c18fe9.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -36,37 +35,36 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
-%half_0x1p_0 = OpConstant %half 0x1p+0
+%half_0x1_5bcp_1 = OpConstant %half 0x1.5bcp+1
 %_ptr_Function_half = OpTypePointer Function %half
-         %19 = OpConstantNull %half
-         %20 = OpTypeFunction %v4float
+         %17 = OpConstantNull %half
+         %18 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
  %exp_c18fe9 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_half Function %19
-         %13 = OpExtInst %half %15 Exp %half_0x1p_0
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_half Function %17
+               OpStore %res %half_0x1_5bcp_1
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %20
-         %22 = OpLabel
-         %23 = OpFunctionCall %void %exp_c18fe9
+%vertex_main_inner = OpFunction %v4float None %18
+         %20 = OpLabel
+         %21 = OpFunctionCall %void %exp_c18fe9
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %26
+         %23 = OpLabel
+         %24 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %24
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp_c18fe9
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %exp_c18fe9
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp_c18fe9
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %exp_c18fe9
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.dxc.hlsl
index a95aa4a..5d794f9 100644
--- a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp_d98450() {
-  float3 res = exp((1.0f).xxx);
+  float3 res = (2.718281746f).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.fxc.hlsl
index a95aa4a..5d794f9 100644
--- a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp_d98450() {
-  float3 res = exp((1.0f).xxx);
+  float3 res = (2.718281746f).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.glsl
index ded17bf..4074503 100644
--- a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp_d98450() {
-  vec3 res = exp(vec3(1.0f));
+  vec3 res = vec3(2.718281746f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp_d98450() {
-  vec3 res = exp(vec3(1.0f));
+  vec3 res = vec3(2.718281746f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp_d98450() {
-  vec3 res = exp(vec3(1.0f));
+  vec3 res = vec3(2.718281746f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.msl
index 7671076..2c3e2f0 100644
--- a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp_d98450() {
-  float3 res = exp(float3(1.0f));
+  float3 res = float3(2.718281746f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.spvasm
index 0cbf6ac..845e41f 100644
--- a/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp/d98450.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -32,37 +31,37 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
     %v3float = OpTypeVector %float 3
-    %float_1 = OpConstant %float 1
-         %17 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v3float %float_2_71828175 %float_2_71828175 %float_2_71828175
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-         %20 = OpConstantNull %v3float
-         %21 = OpTypeFunction %v4float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
  %exp_d98450 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v3float Function %20
-         %13 = OpExtInst %v3float %15 Exp %17
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %21
-         %23 = OpLabel
-         %24 = OpFunctionCall %void %exp_d98450
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_d98450
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %27
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp_d98450
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_d98450
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp_d98450
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_d98450
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl b/test/tint/builtins/gen/literal/exp/dad791.wgsl
new file mode 100644
index 0000000..d9547b2
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<4, fa>) -> vec<4, fa>
+fn exp_dad791() {
+  var res = exp(vec4(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_dad791();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_dad791();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_dad791();
+}
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b4228d0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_dad791() {
+  float4 res = (2.718281746f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  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() {
+  exp_dad791();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_dad791();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b4228d0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_dad791() {
+  float4 res = (2.718281746f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  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() {
+  exp_dad791();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_dad791();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.glsl
new file mode 100644
index 0000000..1adc457
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_dad791();
+  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;
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+void fragment_main() {
+  exp_dad791();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+void compute_main() {
+  exp_dad791();
+}
+
+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/exp/dad791.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.msl
new file mode 100644
index 0000000..c445389
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_dad791() {
+  float4 res = float4(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_dad791();
+  return;
+}
+
+kernel void compute_main() {
+  exp_dad791();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.spvasm
new file mode 100644
index 0000000..14e3c5c
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.spvasm
@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 31
+; 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 %exp_dad791 "exp_dad791"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+%float_2_71828175 = OpConstant %float 2.71828175
+         %14 = OpConstantComposite %v4float %float_2_71828175 %float_2_71828175 %float_2_71828175 %float_2_71828175
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_dad791 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %res %14
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp_dad791
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp_dad791
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_dad791
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.wgsl
new file mode 100644
index 0000000..eb7e4c5
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp/dad791.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp_dad791() {
+  var res = exp(vec4(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_dad791();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_dad791();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_dad791();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.dxc.hlsl
index b86be99..1e6efb6 100644
--- a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_151a4c() {
-  vector<float16_t, 2> res = exp2((float16_t(1.0h)).xx);
+  vector<float16_t, 2> res = (float16_t(2.0h)).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.glsl
index e7a27302..a399636 100644
--- a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_151a4c() {
-  f16vec2 res = exp2(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.0hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp2_151a4c() {
-  f16vec2 res = exp2(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.0hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_151a4c() {
-  f16vec2 res = exp2(f16vec2(1.0hf));
+  f16vec2 res = f16vec2(2.0hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.msl
index 648a584..4a0818b 100644
--- a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_151a4c() {
-  half2 res = exp2(half2(1.0h));
+  half2 res = half2(2.0h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.spvasm
index 21a8c06..3d4fc8e 100644
--- a/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/151a4c.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v2half = OpTypeVector %half 2
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
+%half_0x1p_1 = OpConstant %half 0x1p+1
+         %16 = OpConstantComposite %v2half %half_0x1p_1 %half_0x1p_1
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-         %21 = OpConstantNull %v2half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v2half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
 %exp2_151a4c = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v2half Function %21
-         %13 = OpExtInst %v2half %16 Exp2 %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v2half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp2_151a4c
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp2_151a4c
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp2_151a4c
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_151a4c
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp2_151a4c
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp2_151a4c
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl
new file mode 100644
index 0000000..980fe29
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<2, fa>) -> vec<2, fa>
+fn exp2_18aa76() {
+  var res = exp2(vec2(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_18aa76();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_18aa76();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_18aa76();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..e787438
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_18aa76() {
+  float2 res = (2.0f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  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() {
+  exp2_18aa76();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_18aa76();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..e787438
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_18aa76() {
+  float2 res = (2.0f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  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() {
+  exp2_18aa76();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_18aa76();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.glsl
new file mode 100644
index 0000000..4dea06a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_18aa76();
+  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;
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+void fragment_main() {
+  exp2_18aa76();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+void compute_main() {
+  exp2_18aa76();
+}
+
+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/exp2/18aa76.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.msl
new file mode 100644
index 0000000..da4207d
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_18aa76() {
+  float2 res = float2(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_18aa76();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_18aa76();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.spvasm
new file mode 100644
index 0000000..569ab63a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp2_18aa76 "exp2_18aa76"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v2float = OpTypeVector %float 2
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v2float %float_2 %float_2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_18aa76 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_18aa76
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_18aa76
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_18aa76
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.wgsl
new file mode 100644
index 0000000..3f0a8ff
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/18aa76.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp2_18aa76() {
+  var res = exp2(vec2(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_18aa76();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_18aa76();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_18aa76();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.dxc.hlsl
index 3988832..1b85c20 100644
--- a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_1f8680() {
-  float3 res = exp2((1.0f).xxx);
+  float3 res = (2.0f).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.fxc.hlsl
index 3988832..1b85c20 100644
--- a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_1f8680() {
-  float3 res = exp2((1.0f).xxx);
+  float3 res = (2.0f).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.glsl
index a92cdd8..1b8574a 100644
--- a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp2_1f8680() {
-  vec3 res = exp2(vec3(1.0f));
+  vec3 res = vec3(2.0f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp2_1f8680() {
-  vec3 res = exp2(vec3(1.0f));
+  vec3 res = vec3(2.0f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp2_1f8680() {
-  vec3 res = exp2(vec3(1.0f));
+  vec3 res = vec3(2.0f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.msl
index 04fd287..17bb4df 100644
--- a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_1f8680() {
-  float3 res = exp2(float3(1.0f));
+  float3 res = float3(2.0f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.spvasm
index 87378ba..8b711e0 100644
--- a/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/1f8680.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -32,37 +31,37 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
     %v3float = OpTypeVector %float 3
-    %float_1 = OpConstant %float 1
-         %17 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v3float %float_2 %float_2 %float_2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-         %20 = OpConstantNull %v3float
-         %21 = OpTypeFunction %v4float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
 %exp2_1f8680 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v3float Function %20
-         %13 = OpExtInst %v3float %15 Exp2 %17
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %21
-         %23 = OpLabel
-         %24 = OpFunctionCall %void %exp2_1f8680
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_1f8680
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %27
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp2_1f8680
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_1f8680
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp2_1f8680
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_1f8680
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl b/test/tint/builtins/gen/literal/exp2/303753.wgsl
new file mode 100644
index 0000000..769be3a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<3, fa>) -> vec<3, fa>
+fn exp2_303753() {
+  var res = exp2(vec3(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_303753();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_303753();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_303753();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c41710e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_303753() {
+  float3 res = (2.0f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  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() {
+  exp2_303753();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_303753();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c41710e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_303753() {
+  float3 res = (2.0f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  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() {
+  exp2_303753();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_303753();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.glsl
new file mode 100644
index 0000000..131c8f4
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_303753();
+  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;
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+void fragment_main() {
+  exp2_303753();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+void compute_main() {
+  exp2_303753();
+}
+
+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/exp2/303753.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.msl
new file mode 100644
index 0000000..ba3a2b0
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_303753() {
+  float3 res = float3(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_303753();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_303753();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.spvasm
new file mode 100644
index 0000000..9a276fe
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp2_303753 "exp2_303753"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v3float = OpTypeVector %float 3
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v3float %float_2 %float_2 %float_2
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_303753 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_303753
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_303753
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_303753
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.wgsl
new file mode 100644
index 0000000..7f3471a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/303753.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp2_303753() {
+  var res = exp2(vec3(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_303753();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_303753();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_303753();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.dxc.hlsl
index df31b74..6949b49 100644
--- a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_751377() {
-  vector<float16_t, 3> res = exp2((float16_t(1.0h)).xxx);
+  vector<float16_t, 3> res = (float16_t(2.0h)).xxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.glsl
index 92bdff7..8aa2e87 100644
--- a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_751377() {
-  f16vec3 res = exp2(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.0hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp2_751377() {
-  f16vec3 res = exp2(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.0hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_751377() {
-  f16vec3 res = exp2(f16vec3(1.0hf));
+  f16vec3 res = f16vec3(2.0hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.msl
index 94ad2ef..cf71cdd 100644
--- a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_751377() {
-  half3 res = exp2(half3(1.0h));
+  half3 res = half3(2.0h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.spvasm
index c9e1e3a..5b1fcd0 100644
--- a/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/751377.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v3half = OpTypeVector %half 3
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
+%half_0x1p_1 = OpConstant %half 0x1p+1
+         %16 = OpConstantComposite %v3half %half_0x1p_1 %half_0x1p_1 %half_0x1p_1
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-         %21 = OpConstantNull %v3half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v3half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
 %exp2_751377 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v3half Function %21
-         %13 = OpExtInst %v3half %16 Exp2 %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v3half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp2_751377
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp2_751377
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp2_751377
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_751377
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp2_751377
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp2_751377
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl
new file mode 100644
index 0000000..9c63098
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<4, fa>) -> vec<4, fa>
+fn exp2_8bd72d() {
+  var res = exp2(vec4(1.));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_8bd72d();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_8bd72d();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_8bd72d();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f67ab78
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_8bd72d() {
+  float4 res = (2.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  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() {
+  exp2_8bd72d();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_8bd72d();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f67ab78
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_8bd72d() {
+  float4 res = (2.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  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() {
+  exp2_8bd72d();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_8bd72d();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.glsl
new file mode 100644
index 0000000..8cc964a
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_8bd72d();
+  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;
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+void fragment_main() {
+  exp2_8bd72d();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+void compute_main() {
+  exp2_8bd72d();
+}
+
+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/exp2/8bd72d.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.msl
new file mode 100644
index 0000000..cf8ab6f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_8bd72d() {
+  float4 res = float4(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_8bd72d();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_8bd72d();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.spvasm
new file mode 100644
index 0000000..fc15fb6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.spvasm
@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 31
+; 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 %exp2_8bd72d "exp2_8bd72d"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_2 = OpConstant %float 2
+         %14 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_8bd72d = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %res %14
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp2_8bd72d
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp2_8bd72d
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_8bd72d
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.wgsl
new file mode 100644
index 0000000..75bbe79
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/8bd72d.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp2_8bd72d() {
+  var res = exp2(vec4(1.0));
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_8bd72d();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_8bd72d();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_8bd72d();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.dxc.hlsl
index e112642..d941f89 100644
--- a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_a9d0a7() {
-  float4 res = exp2((1.0f).xxxx);
+  float4 res = (2.0f).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.fxc.hlsl
index e112642..d941f89 100644
--- a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_a9d0a7() {
-  float4 res = exp2((1.0f).xxxx);
+  float4 res = (2.0f).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.glsl
index 64e9bfa..4d060ab 100644
--- a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp2_a9d0a7() {
-  vec4 res = exp2(vec4(1.0f));
+  vec4 res = vec4(2.0f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp2_a9d0a7() {
-  vec4 res = exp2(vec4(1.0f));
+  vec4 res = vec4(2.0f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp2_a9d0a7() {
-  vec4 res = exp2(vec4(1.0f));
+  vec4 res = vec4(2.0f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.msl
index 7c35eb7..cdadda0 100644
--- a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_a9d0a7() {
-  float4 res = exp2(float4(1.0f));
+  float4 res = float4(2.0f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.spvasm
index 21d06ef..3773fa1 100644
--- a/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/a9d0a7.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 32
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
-         %14 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -31,36 +30,36 @@
 %vertex_point_size = OpVariable %_ptr_Output_float Output %8
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
-    %float_1 = OpConstant %float 1
-         %16 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+    %float_2 = OpConstant %float 2
+         %14 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %19 = OpTypeFunction %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
 %exp2_a9d0a7 = OpFunction %void None %9
          %12 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function %5
-         %13 = OpExtInst %v4float %14 Exp2 %16
-               OpStore %res %13
+               OpStore %res %14
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %19
-         %21 = OpLabel
-         %22 = OpFunctionCall %void %exp2_a9d0a7
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp2_a9d0a7
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %25
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %void %exp2_a9d0a7
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp2_a9d0a7
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %30 = OpLabel
-         %31 = OpFunctionCall %void %exp2_a9d0a7
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_a9d0a7
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.dxc.hlsl
index b551f3f..794e9e2 100644
--- a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_b408e4() {
-  float16_t res = exp2(float16_t(1.0h));
+  float16_t res = float16_t(2.0h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.glsl
index 84e9ac1..e87b6f9 100644
--- a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_b408e4() {
-  float16_t res = exp2(1.0hf);
+  float16_t res = 2.0hf;
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp2_b408e4() {
-  float16_t res = exp2(1.0hf);
+  float16_t res = 2.0hf;
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_b408e4() {
-  float16_t res = exp2(1.0hf);
+  float16_t res = 2.0hf;
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.msl
index d28fe02..2691f7f 100644
--- a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_b408e4() {
-  half res = exp2(1.0h);
+  half res = 2.0h;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.spvasm
index ce19204..b8aab1c 100644
--- a/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/b408e4.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -36,37 +35,36 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
-%half_0x1p_0 = OpConstant %half 0x1p+0
+%half_0x1p_1 = OpConstant %half 0x1p+1
 %_ptr_Function_half = OpTypePointer Function %half
-         %19 = OpConstantNull %half
-         %20 = OpTypeFunction %v4float
+         %17 = OpConstantNull %half
+         %18 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
 %exp2_b408e4 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_half Function %19
-         %13 = OpExtInst %half %15 Exp2 %half_0x1p_0
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_half Function %17
+               OpStore %res %half_0x1p_1
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %20
-         %22 = OpLabel
-         %23 = OpFunctionCall %void %exp2_b408e4
+%vertex_main_inner = OpFunction %v4float None %18
+         %20 = OpLabel
+         %21 = OpFunctionCall %void %exp2_b408e4
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %26
+         %23 = OpLabel
+         %24 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %24
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp2_b408e4
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %exp2_b408e4
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp2_b408e4
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %exp2_b408e4
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.dxc.hlsl
index 6bec5e24..d490385 100644
--- a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_d6777c() {
-  float2 res = exp2((1.0f).xx);
+  float2 res = (2.0f).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.fxc.hlsl
index 6bec5e24..d490385 100644
--- a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_d6777c() {
-  float2 res = exp2((1.0f).xx);
+  float2 res = (2.0f).xx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.glsl
index 9ab3430..8acdc0b 100644
--- a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp2_d6777c() {
-  vec2 res = exp2(vec2(1.0f));
+  vec2 res = vec2(2.0f);
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp2_d6777c() {
-  vec2 res = exp2(vec2(1.0f));
+  vec2 res = vec2(2.0f);
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp2_d6777c() {
-  vec2 res = exp2(vec2(1.0f));
+  vec2 res = vec2(2.0f);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.msl
index befa16a..154fccc 100644
--- a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_d6777c() {
-  float2 res = exp2(float2(1.0f));
+  float2 res = float2(2.0f);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.spvasm
index f7d33f8..977f17e 100644
--- a/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/d6777c.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 34
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
-         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -32,37 +31,37 @@
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
     %v2float = OpTypeVector %float 2
-    %float_1 = OpConstant %float 1
-         %17 = OpConstantComposite %v2float %float_1 %float_1
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v2float %float_2 %float_2
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-         %20 = OpConstantNull %v2float
-         %21 = OpTypeFunction %v4float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
 %exp2_d6777c = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v2float Function %20
-         %13 = OpExtInst %v2float %15 Exp2 %17
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %21
-         %23 = OpLabel
-         %24 = OpFunctionCall %void %exp2_d6777c
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_d6777c
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %27
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp2_d6777c
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_d6777c
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %exp2_d6777c
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_d6777c
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.dxc.hlsl
index 0a9e48b..66dac75 100644
--- a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.fxc.hlsl
index 0a9e48b..66dac75 100644
--- a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.fxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.glsl
index d209b71..8b3865d 100644
--- a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 vec4 vertex_main() {
@@ -21,7 +21,7 @@
 precision mediump float;
 
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 void fragment_main() {
@@ -35,7 +35,7 @@
 #version 310 es
 
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.msl
index 7c86c2a..6dc4efb 100644
--- a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_dea523() {
-  float res = exp2(1.0f);
+  float res = 2.0f;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.spvasm
index ce3d3a9..81dd5e9 100644
--- a/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/dea523.wgsl.expected.spvasm
@@ -1,10 +1,9 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 31
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
-         %14 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -31,35 +30,35 @@
 %vertex_point_size = OpVariable %_ptr_Output_float Output %8
        %void = OpTypeVoid
           %9 = OpTypeFunction %void
-    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
 %_ptr_Function_float = OpTypePointer Function %float
-         %18 = OpTypeFunction %v4float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
 %exp2_dea523 = OpFunction %void None %9
          %12 = OpLabel
         %res = OpVariable %_ptr_Function_float Function %8
-         %13 = OpExtInst %float %14 Exp2 %float_1
-               OpStore %res %13
+               OpStore %res %float_2
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %18
-         %20 = OpLabel
-         %21 = OpFunctionCall %void %exp2_dea523
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp2_dea523
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %24
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %26 = OpLabel
-         %27 = OpFunctionCall %void %exp2_dea523
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp2_dea523
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %exp2_dea523
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_dea523
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl
new file mode 100644
index 0000000..e82d413
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl
@@ -0,0 +1,43 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(fa) -> fa
+fn exp2_f4f0f1() {
+  var res = exp2(1.);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_f4f0f1();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_f4f0f1();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_f4f0f1();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..35b7bc2
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  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() {
+  exp2_f4f0f1();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..35b7bc2
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  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() {
+  exp2_f4f0f1();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.glsl
new file mode 100644
index 0000000..7180ee6
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+vec4 vertex_main() {
+  exp2_f4f0f1();
+  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;
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+void fragment_main() {
+  exp2_f4f0f1();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+void compute_main() {
+  exp2_f4f0f1();
+}
+
+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/exp2/f4f0f1.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.msl
new file mode 100644
index 0000000..449693f
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_f4f0f1();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.spvasm
new file mode 100644
index 0000000..6aeb03e
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %exp2_f4f0f1 "exp2_f4f0f1"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_2 = OpConstant %float 2
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_f4f0f1 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_2
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.wgsl
new file mode 100644
index 0000000..c490ff1
--- /dev/null
+++ b/test/tint/builtins/gen/literal/exp2/f4f0f1.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+fn exp2_f4f0f1() {
+  var res = exp2(1.0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_f4f0f1();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_f4f0f1();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_f4f0f1();
+}
diff --git a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.dxc.hlsl
index 1e83141..7b48050 100644
--- a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.dxc.hlsl
@@ -1,5 +1,5 @@
 void exp2_ffa827() {
-  vector<float16_t, 4> res = exp2((float16_t(1.0h)).xxxx);
+  vector<float16_t, 4> res = (float16_t(2.0h)).xxxx;
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.glsl b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.glsl
index 90847d5..935d0f3 100644
--- a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_ffa827() {
-  f16vec4 res = exp2(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.0hf);
 }
 
 vec4 vertex_main() {
@@ -23,7 +23,7 @@
 precision mediump float;
 
 void exp2_ffa827() {
-  f16vec4 res = exp2(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.0hf);
 }
 
 void fragment_main() {
@@ -38,7 +38,7 @@
 #extension GL_AMD_gpu_shader_half_float : require
 
 void exp2_ffa827() {
-  f16vec4 res = exp2(f16vec4(1.0hf));
+  f16vec4 res = f16vec4(2.0hf);
 }
 
 void compute_main() {
diff --git a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.msl b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.msl
index 46061e3..75b4b67 100644
--- a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void exp2_ffa827() {
-  half4 res = exp2(half4(1.0h));
+  half4 res = half4(2.0h);
 }
 
 struct tint_symbol {
diff --git a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.spvasm
index 71e376e..43ddda6 100644
--- a/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/exp2/ffa827.wgsl.expected.spvasm
@@ -1,14 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
                OpCapability StorageInputOutput16
-         %16 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vertex_main "vertex_main" %value %vertex_point_size
                OpEntryPoint Fragment %fragment_main "fragment_main"
@@ -37,38 +36,37 @@
           %9 = OpTypeFunction %void
        %half = OpTypeFloat 16
      %v4half = OpTypeVector %half 4
-%half_0x1p_0 = OpConstant %half 0x1p+0
-         %18 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
+%half_0x1p_1 = OpConstant %half 0x1p+1
+         %16 = OpConstantComposite %v4half %half_0x1p_1 %half_0x1p_1 %half_0x1p_1 %half_0x1p_1
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-         %21 = OpConstantNull %v4half
-         %22 = OpTypeFunction %v4float
+         %19 = OpConstantNull %v4half
+         %20 = OpTypeFunction %v4float
     %float_1 = OpConstant %float 1
 %exp2_ffa827 = OpFunction %void None %9
          %12 = OpLabel
-        %res = OpVariable %_ptr_Function_v4half Function %21
-         %13 = OpExtInst %v4half %16 Exp2 %18
-               OpStore %res %13
+        %res = OpVariable %_ptr_Function_v4half Function %19
+               OpStore %res %16
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %22
-         %24 = OpLabel
-         %25 = OpFunctionCall %void %exp2_ffa827
+%vertex_main_inner = OpFunction %v4float None %20
+         %22 = OpLabel
+         %23 = OpFunctionCall %void %exp2_ffa827
                OpReturnValue %5
                OpFunctionEnd
 %vertex_main = OpFunction %void None %9
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %value %28
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %26
                OpStore %vertex_point_size %float_1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %9
-         %31 = OpLabel
-         %32 = OpFunctionCall %void %exp2_ffa827
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_ffa827
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %9
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %exp2_ffa827
+         %32 = OpLabel
+         %33 = OpFunctionCall %void %exp2_ffa827
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c4e18de
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_08eb56();
+  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() {
+  dot_08eb56();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_08eb56();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c4e18de
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_08eb56();
+  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() {
+  dot_08eb56();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_08eb56();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.glsl
new file mode 100644
index 0000000..fde4529
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+vec4 vertex_main() {
+  dot_08eb56();
+  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;
+
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+void fragment_main() {
+  dot_08eb56();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+void compute_main() {
+  dot_08eb56();
+}
+
+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/dot/08eb56.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.msl
new file mode 100644
index 0000000..a442896
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_08eb56() {
+  float res = 4.0f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_08eb56();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_08eb56();
+  return;
+}
+
+kernel void compute_main() {
+  dot_08eb56();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.spvasm
new file mode 100644
index 0000000..e5558a9
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %dot_08eb56 "dot_08eb56"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_4 = OpConstant %float 4
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_08eb56 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_4
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %dot_08eb56
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %dot_08eb56
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %dot_08eb56
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.wgsl
new file mode 100644
index 0000000..44a38ce
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/08eb56.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_08eb56() {
+  const arg_0 = vec4(1.0);
+  const arg_1 = vec4(1.0);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_08eb56();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_08eb56();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_08eb56();
+}
diff --git a/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..46e88b5
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_0d2c2e();
+  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() {
+  dot_0d2c2e();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_0d2c2e();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..46e88b5
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_0d2c2e();
+  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() {
+  dot_0d2c2e();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_0d2c2e();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.glsl
new file mode 100644
index 0000000..56f8ba0
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+vec4 vertex_main() {
+  dot_0d2c2e();
+  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;
+
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+void fragment_main() {
+  dot_0d2c2e();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+void compute_main() {
+  dot_0d2c2e();
+}
+
+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/dot/0d2c2e.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.msl
new file mode 100644
index 0000000..9e750d4
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_0d2c2e() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_0d2c2e();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_0d2c2e();
+  return;
+}
+
+kernel void compute_main() {
+  dot_0d2c2e();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.spvasm
new file mode 100644
index 0000000..bb94b74
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %dot_0d2c2e "dot_0d2c2e"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_2 = OpConstant %float 2
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_0d2c2e = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_2
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %dot_0d2c2e
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %dot_0d2c2e
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %dot_0d2c2e
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.wgsl
new file mode 100644
index 0000000..a68df20
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/0d2c2e.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_0d2c2e() {
+  const arg_0 = vec2(1.0);
+  const arg_1 = vec2(1.0);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_0d2c2e();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_0d2c2e();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_0d2c2e();
+}
diff --git a/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..77562dc
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_14bc63() {
+  int res = 2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_14bc63();
+  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() {
+  dot_14bc63();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_14bc63();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..77562dc
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_14bc63() {
+  int res = 2;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_14bc63();
+  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() {
+  dot_14bc63();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_14bc63();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.glsl
new file mode 100644
index 0000000..ee01341
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_14bc63() {
+  int res = 2;
+}
+
+vec4 vertex_main() {
+  dot_14bc63();
+  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;
+
+void dot_14bc63() {
+  int res = 2;
+}
+
+void fragment_main() {
+  dot_14bc63();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_14bc63() {
+  int res = 2;
+}
+
+void compute_main() {
+  dot_14bc63();
+}
+
+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/dot/14bc63.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.msl
new file mode 100644
index 0000000..6f2f467
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_14bc63() {
+  int res = 2;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_14bc63();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_14bc63();
+  return;
+}
+
+kernel void compute_main() {
+  dot_14bc63();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.spvasm
new file mode 100644
index 0000000..f454100
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.spvasm
@@ -0,0 +1,66 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 32
+; 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 %dot_14bc63 "dot_14bc63"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_2 = OpConstant %int 2
+%_ptr_Function_int = OpTypePointer Function %int
+         %17 = OpConstantNull %int
+         %18 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_14bc63 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_int Function %17
+               OpStore %res %int_2
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %18
+         %20 = OpLabel
+         %21 = OpFunctionCall %void %dot_14bc63
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %23 = OpLabel
+         %24 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %24
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %dot_14bc63
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %dot_14bc63
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.wgsl
new file mode 100644
index 0000000..2d96597
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/14bc63.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_14bc63() {
+  const arg_0 = vec2(1);
+  const arg_1 = vec2(1);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_14bc63();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_14bc63();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_14bc63();
+}
diff --git a/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b6e6077
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_5a4c8f();
+  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() {
+  dot_5a4c8f();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_5a4c8f();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b6e6077
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_5a4c8f();
+  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() {
+  dot_5a4c8f();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_5a4c8f();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.glsl
new file mode 100644
index 0000000..bf3a69a
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+vec4 vertex_main() {
+  dot_5a4c8f();
+  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;
+
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+void fragment_main() {
+  dot_5a4c8f();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+void compute_main() {
+  dot_5a4c8f();
+}
+
+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/dot/5a4c8f.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.msl
new file mode 100644
index 0000000..e3ba3f5
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_5a4c8f() {
+  float res = 3.0f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_5a4c8f();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_5a4c8f();
+  return;
+}
+
+kernel void compute_main() {
+  dot_5a4c8f();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.spvasm
new file mode 100644
index 0000000..e212ecb
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %dot_5a4c8f "dot_5a4c8f"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_3 = OpConstant %float 3
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_5a4c8f = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_3
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %dot_5a4c8f
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %dot_5a4c8f
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %dot_5a4c8f
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.wgsl
new file mode 100644
index 0000000..1a8f15e
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/5a4c8f.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_5a4c8f() {
+  const arg_0 = vec3(1.0);
+  const arg_1 = vec3(1.0);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_5a4c8f();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_5a4c8f();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_5a4c8f();
+}
diff --git a/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c35aa55
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_c11efe() {
+  int res = 3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_c11efe();
+  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() {
+  dot_c11efe();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_c11efe();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c35aa55
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_c11efe() {
+  int res = 3;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_c11efe();
+  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() {
+  dot_c11efe();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_c11efe();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.glsl
new file mode 100644
index 0000000..0a21a3d
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_c11efe() {
+  int res = 3;
+}
+
+vec4 vertex_main() {
+  dot_c11efe();
+  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;
+
+void dot_c11efe() {
+  int res = 3;
+}
+
+void fragment_main() {
+  dot_c11efe();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_c11efe() {
+  int res = 3;
+}
+
+void compute_main() {
+  dot_c11efe();
+}
+
+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/dot/c11efe.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.msl
new file mode 100644
index 0000000..a177d81
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_c11efe() {
+  int res = 3;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_c11efe();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_c11efe();
+  return;
+}
+
+kernel void compute_main() {
+  dot_c11efe();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.spvasm
new file mode 100644
index 0000000..d2fdf7d
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.spvasm
@@ -0,0 +1,66 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 32
+; 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 %dot_c11efe "dot_c11efe"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_3 = OpConstant %int 3
+%_ptr_Function_int = OpTypePointer Function %int
+         %17 = OpConstantNull %int
+         %18 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_c11efe = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_int Function %17
+               OpStore %res %int_3
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %18
+         %20 = OpLabel
+         %21 = OpFunctionCall %void %dot_c11efe
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %23 = OpLabel
+         %24 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %24
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %dot_c11efe
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %dot_c11efe
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.wgsl
new file mode 100644
index 0000000..36e2f45
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/c11efe.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_c11efe() {
+  const arg_0 = vec3(1);
+  const arg_1 = vec3(1);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_c11efe();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_c11efe();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_c11efe();
+}
diff --git a/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..348af30
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_eb9fbf();
+  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() {
+  dot_eb9fbf();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_eb9fbf();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..348af30
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  dot_eb9fbf();
+  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() {
+  dot_eb9fbf();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  dot_eb9fbf();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.glsl b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.glsl
new file mode 100644
index 0000000..a10a639
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+vec4 vertex_main() {
+  dot_eb9fbf();
+  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;
+
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+void fragment_main() {
+  dot_eb9fbf();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+void compute_main() {
+  dot_eb9fbf();
+}
+
+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/dot/eb9fbf.wgsl.expected.msl b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.msl
new file mode 100644
index 0000000..3296741
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void dot_eb9fbf() {
+  int res = 4;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  dot_eb9fbf();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  dot_eb9fbf();
+  return;
+}
+
+kernel void compute_main() {
+  dot_eb9fbf();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.spvasm
new file mode 100644
index 0000000..de51f60
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.spvasm
@@ -0,0 +1,66 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 32
+; 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 %dot_eb9fbf "dot_eb9fbf"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_4 = OpConstant %int 4
+%_ptr_Function_int = OpTypePointer Function %int
+         %17 = OpConstantNull %int
+         %18 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %dot_eb9fbf = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_int Function %17
+               OpStore %res %int_4
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %18
+         %20 = OpLabel
+         %21 = OpFunctionCall %void %dot_eb9fbf
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %23 = OpLabel
+         %24 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %24
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %27 = OpLabel
+         %28 = OpFunctionCall %void %dot_eb9fbf
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %30 = OpLabel
+         %31 = OpFunctionCall %void %dot_eb9fbf
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.wgsl b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.wgsl
new file mode 100644
index 0000000..7c0da3c
--- /dev/null
+++ b/test/tint/builtins/gen/var/dot/eb9fbf.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+fn dot_eb9fbf() {
+  const arg_0 = vec4(1);
+  const arg_1 = vec4(1);
+  var res = dot(arg_0, arg_1);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  dot_eb9fbf();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  dot_eb9fbf();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  dot_eb9fbf();
+}
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl
new file mode 100644
index 0000000..988e2f9
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(fa) -> fa
+fn exp_49e4c5() {
+  const arg_0 = 1.;
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_49e4c5();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_49e4c5();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_49e4c5();
+}
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..a370f26
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  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() {
+  exp_49e4c5();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_49e4c5();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..a370f26
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  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() {
+  exp_49e4c5();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_49e4c5();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.glsl
new file mode 100644
index 0000000..304cb4d
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+vec4 vertex_main() {
+  exp_49e4c5();
+  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;
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+void fragment_main() {
+  exp_49e4c5();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+void compute_main() {
+  exp_49e4c5();
+}
+
+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/exp/49e4c5.wgsl.expected.msl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.msl
new file mode 100644
index 0000000..94c050b
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_49e4c5() {
+  float res = 2.718281746f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_49e4c5();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_49e4c5();
+  return;
+}
+
+kernel void compute_main() {
+  exp_49e4c5();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.spvasm
new file mode 100644
index 0000000..9cb7981
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %exp_49e4c5 "exp_49e4c5"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+%float_2_71828175 = OpConstant %float 2.71828175
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_49e4c5 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_2_71828175
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp_49e4c5
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp_49e4c5
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_49e4c5
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.wgsl
new file mode 100644
index 0000000..c863f84
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/49e4c5.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp_49e4c5() {
+  const arg_0 = 1.0;
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_49e4c5();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_49e4c5();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_49e4c5();
+}
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl b/test/tint/builtins/gen/var/exp/699629.wgsl
new file mode 100644
index 0000000..25854f1
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<2, fa>) -> vec<2, fa>
+fn exp_699629() {
+  const arg_0 = vec2(1.);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_699629();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_699629();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_699629();
+}
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f19809c
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_699629() {
+  float2 res = (2.718281746f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  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() {
+  exp_699629();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_699629();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f19809c
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_699629() {
+  float2 res = (2.718281746f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  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() {
+  exp_699629();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_699629();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.glsl
new file mode 100644
index 0000000..93856b5
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_699629();
+  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;
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+void fragment_main() {
+  exp_699629();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_699629() {
+  vec2 res = vec2(2.718281746f);
+}
+
+void compute_main() {
+  exp_699629();
+}
+
+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/exp/699629.wgsl.expected.msl b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.msl
new file mode 100644
index 0000000..e68e3dd
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_699629() {
+  float2 res = float2(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_699629();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_699629();
+  return;
+}
+
+kernel void compute_main() {
+  exp_699629();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.spvasm
new file mode 100644
index 0000000..c607906
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp_699629 "exp_699629"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v2float = OpTypeVector %float 2
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v2float %float_2_71828175 %float_2_71828175
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_699629 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_699629
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_699629
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_699629
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp/699629.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.wgsl
new file mode 100644
index 0000000..358d1e1
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/699629.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp_699629() {
+  const arg_0 = vec2(1.0);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_699629();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_699629();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_699629();
+}
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl
new file mode 100644
index 0000000..4cc1f52
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<3, fa>) -> vec<3, fa>
+fn exp_bda5bb() {
+  const arg_0 = vec3(1.);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_bda5bb();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_bda5bb();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_bda5bb();
+}
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..ea132ce
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_bda5bb() {
+  float3 res = (2.718281746f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  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() {
+  exp_bda5bb();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_bda5bb();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..ea132ce
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_bda5bb() {
+  float3 res = (2.718281746f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  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() {
+  exp_bda5bb();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_bda5bb();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.glsl
new file mode 100644
index 0000000..65cb0f6
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_bda5bb();
+  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;
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+void fragment_main() {
+  exp_bda5bb();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_bda5bb() {
+  vec3 res = vec3(2.718281746f);
+}
+
+void compute_main() {
+  exp_bda5bb();
+}
+
+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/exp/bda5bb.wgsl.expected.msl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.msl
new file mode 100644
index 0000000..46be400
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_bda5bb() {
+  float3 res = float3(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_bda5bb();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_bda5bb();
+  return;
+}
+
+kernel void compute_main() {
+  exp_bda5bb();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.spvasm
new file mode 100644
index 0000000..018b829
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp_bda5bb "exp_bda5bb"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v3float = OpTypeVector %float 3
+%float_2_71828175 = OpConstant %float 2.71828175
+         %15 = OpConstantComposite %v3float %float_2_71828175 %float_2_71828175 %float_2_71828175
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_bda5bb = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp_bda5bb
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp_bda5bb
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp_bda5bb
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.wgsl
new file mode 100644
index 0000000..2d3f471
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/bda5bb.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp_bda5bb() {
+  const arg_0 = vec3(1.0);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_bda5bb();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_bda5bb();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_bda5bb();
+}
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl b/test/tint/builtins/gen/var/exp/dad791.wgsl
new file mode 100644
index 0000000..4977119
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp(vec<4, fa>) -> vec<4, fa>
+fn exp_dad791() {
+  const arg_0 = vec4(1.);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_dad791();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_dad791();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_dad791();
+}
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b4228d0
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp_dad791() {
+  float4 res = (2.718281746f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  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() {
+  exp_dad791();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_dad791();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b4228d0
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp_dad791() {
+  float4 res = (2.718281746f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  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() {
+  exp_dad791();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp_dad791();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.glsl
new file mode 100644
index 0000000..1adc457
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+vec4 vertex_main() {
+  exp_dad791();
+  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;
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+void fragment_main() {
+  exp_dad791();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp_dad791() {
+  vec4 res = vec4(2.718281746f);
+}
+
+void compute_main() {
+  exp_dad791();
+}
+
+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/exp/dad791.wgsl.expected.msl b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.msl
new file mode 100644
index 0000000..c445389
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp_dad791() {
+  float4 res = float4(2.718281746f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp_dad791();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp_dad791();
+  return;
+}
+
+kernel void compute_main() {
+  exp_dad791();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.spvasm
new file mode 100644
index 0000000..14e3c5c
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.spvasm
@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 31
+; 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 %exp_dad791 "exp_dad791"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+%float_2_71828175 = OpConstant %float 2.71828175
+         %14 = OpConstantComposite %v4float %float_2_71828175 %float_2_71828175 %float_2_71828175 %float_2_71828175
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+ %exp_dad791 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %res %14
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp_dad791
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp_dad791
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp_dad791
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.wgsl
new file mode 100644
index 0000000..9759d19
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp/dad791.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp_dad791() {
+  const arg_0 = vec4(1.0);
+  var res = exp(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp_dad791();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp_dad791();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp_dad791();
+}
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl
new file mode 100644
index 0000000..6121811
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<2, fa>) -> vec<2, fa>
+fn exp2_18aa76() {
+  const arg_0 = vec2(1.);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_18aa76();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_18aa76();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_18aa76();
+}
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..e787438
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_18aa76() {
+  float2 res = (2.0f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  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() {
+  exp2_18aa76();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_18aa76();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..e787438
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_18aa76() {
+  float2 res = (2.0f).xx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  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() {
+  exp2_18aa76();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_18aa76();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.glsl
new file mode 100644
index 0000000..4dea06a
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_18aa76();
+  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;
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+void fragment_main() {
+  exp2_18aa76();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_18aa76() {
+  vec2 res = vec2(2.0f);
+}
+
+void compute_main() {
+  exp2_18aa76();
+}
+
+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/exp2/18aa76.wgsl.expected.msl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.msl
new file mode 100644
index 0000000..da4207d
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_18aa76() {
+  float2 res = float2(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_18aa76();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_18aa76();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_18aa76();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.spvasm
new file mode 100644
index 0000000..569ab63a
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp2_18aa76 "exp2_18aa76"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v2float = OpTypeVector %float 2
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v2float %float_2 %float_2
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+         %18 = OpConstantNull %v2float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_18aa76 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v2float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_18aa76
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_18aa76
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_18aa76
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.wgsl
new file mode 100644
index 0000000..b3ae610
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/18aa76.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp2_18aa76() {
+  const arg_0 = vec2(1.0);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_18aa76();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_18aa76();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_18aa76();
+}
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl b/test/tint/builtins/gen/var/exp2/303753.wgsl
new file mode 100644
index 0000000..8d144b1
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<3, fa>) -> vec<3, fa>
+fn exp2_303753() {
+  const arg_0 = vec3(1.);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_303753();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_303753();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_303753();
+}
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..c41710e
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_303753() {
+  float3 res = (2.0f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  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() {
+  exp2_303753();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_303753();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..c41710e
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_303753() {
+  float3 res = (2.0f).xxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  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() {
+  exp2_303753();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_303753();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.glsl
new file mode 100644
index 0000000..131c8f4
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_303753();
+  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;
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+void fragment_main() {
+  exp2_303753();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_303753() {
+  vec3 res = vec3(2.0f);
+}
+
+void compute_main() {
+  exp2_303753();
+}
+
+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/exp2/303753.wgsl.expected.msl b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.msl
new file mode 100644
index 0000000..ba3a2b0
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_303753() {
+  float3 res = float3(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_303753();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_303753();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_303753();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.spvasm
new file mode 100644
index 0000000..9a276fe
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.spvasm
@@ -0,0 +1,67 @@
+; 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 %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 %exp2_303753 "exp2_303753"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %v3float = OpTypeVector %float 3
+    %float_2 = OpConstant %float 2
+         %15 = OpConstantComposite %v3float %float_2 %float_2 %float_2
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+         %18 = OpConstantNull %v3float
+         %19 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_303753 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v3float Function %18
+               OpStore %res %15
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %19
+         %21 = OpLabel
+         %22 = OpFunctionCall %void %exp2_303753
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %24 = OpLabel
+         %25 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %25
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_303753
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %31 = OpLabel
+         %32 = OpFunctionCall %void %exp2_303753
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.wgsl
new file mode 100644
index 0000000..f11e80a3
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/303753.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp2_303753() {
+  const arg_0 = vec3(1.0);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_303753();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_303753();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_303753();
+}
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl
new file mode 100644
index 0000000..97bdbee
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(vec<4, fa>) -> vec<4, fa>
+fn exp2_8bd72d() {
+  const arg_0 = vec4(1.);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_8bd72d();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_8bd72d();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_8bd72d();
+}
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..f67ab78
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_8bd72d() {
+  float4 res = (2.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  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() {
+  exp2_8bd72d();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_8bd72d();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..f67ab78
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_8bd72d() {
+  float4 res = (2.0f).xxxx;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  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() {
+  exp2_8bd72d();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_8bd72d();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.glsl
new file mode 100644
index 0000000..8cc964a
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+vec4 vertex_main() {
+  exp2_8bd72d();
+  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;
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+void fragment_main() {
+  exp2_8bd72d();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_8bd72d() {
+  vec4 res = vec4(2.0f);
+}
+
+void compute_main() {
+  exp2_8bd72d();
+}
+
+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/exp2/8bd72d.wgsl.expected.msl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.msl
new file mode 100644
index 0000000..cf8ab6f
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_8bd72d() {
+  float4 res = float4(2.0f);
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_8bd72d();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_8bd72d();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_8bd72d();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.spvasm
new file mode 100644
index 0000000..fc15fb6
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.spvasm
@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 31
+; 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 %exp2_8bd72d "exp2_8bd72d"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_2 = OpConstant %float 2
+         %14 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+         %17 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_8bd72d = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_v4float Function %5
+               OpStore %res %14
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %17
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %exp2_8bd72d
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %22 = OpLabel
+         %23 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %23
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %26 = OpLabel
+         %27 = OpFunctionCall %void %exp2_8bd72d
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %29 = OpLabel
+         %30 = OpFunctionCall %void %exp2_8bd72d
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.wgsl
new file mode 100644
index 0000000..3aaba67
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/8bd72d.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp2_8bd72d() {
+  const arg_0 = vec4(1.0);
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_8bd72d();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_8bd72d();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_8bd72d();
+}
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl
new file mode 100644
index 0000000..db9718d
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl
@@ -0,0 +1,44 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   test/tint/builtins/gen/gen.wgsl.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+
+// fn exp2(fa) -> fa
+fn exp2_f4f0f1() {
+  const arg_0 = 1.;
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_f4f0f1();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_f4f0f1();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_f4f0f1();
+}
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..35b7bc2
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  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() {
+  exp2_f4f0f1();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..35b7bc2
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value : SV_Position;
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  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() {
+  exp2_f4f0f1();
+  return;
+}
+
+[numthreads(1, 1, 1)]
+void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.glsl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.glsl
new file mode 100644
index 0000000..7180ee6
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+vec4 vertex_main() {
+  exp2_f4f0f1();
+  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;
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+void fragment_main() {
+  exp2_f4f0f1();
+}
+
+void main() {
+  fragment_main();
+  return;
+}
+#version 310 es
+
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+void compute_main() {
+  exp2_f4f0f1();
+}
+
+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/exp2/f4f0f1.wgsl.expected.msl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.msl
new file mode 100644
index 0000000..449693f
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.msl
@@ -0,0 +1,33 @@
+#include <metal_stdlib>
+
+using namespace metal;
+void exp2_f4f0f1() {
+  float res = 2.0f;
+}
+
+struct tint_symbol {
+  float4 value [[position]];
+};
+
+float4 vertex_main_inner() {
+  exp2_f4f0f1();
+  return float4(0.0f);
+}
+
+vertex tint_symbol vertex_main() {
+  float4 const inner_result = vertex_main_inner();
+  tint_symbol wrapper_result = {};
+  wrapper_result.value = inner_result;
+  return wrapper_result;
+}
+
+fragment void fragment_main() {
+  exp2_f4f0f1();
+  return;
+}
+
+kernel void compute_main() {
+  exp2_f4f0f1();
+  return;
+}
+
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.spvasm
new file mode 100644
index 0000000..6aeb03e
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 30
+; 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 %exp2_f4f0f1 "exp2_f4f0f1"
+               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
+      %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
+       %void = OpTypeVoid
+          %9 = OpTypeFunction %void
+    %float_2 = OpConstant %float 2
+%_ptr_Function_float = OpTypePointer Function %float
+         %16 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+%exp2_f4f0f1 = OpFunction %void None %9
+         %12 = OpLabel
+        %res = OpVariable %_ptr_Function_float Function %8
+               OpStore %res %float_2
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %v4float None %16
+         %18 = OpLabel
+         %19 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturnValue %5
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %9
+         %21 = OpLabel
+         %22 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %value %22
+               OpStore %vertex_point_size %float_1
+               OpReturn
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %9
+         %25 = OpLabel
+         %26 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturn
+               OpFunctionEnd
+%compute_main = OpFunction %void None %9
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %exp2_f4f0f1
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.wgsl b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.wgsl
new file mode 100644
index 0000000..c4637fe
--- /dev/null
+++ b/test/tint/builtins/gen/var/exp2/f4f0f1.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+fn exp2_f4f0f1() {
+  const arg_0 = 1.0;
+  var res = exp2(arg_0);
+}
+
+@vertex
+fn vertex_main() -> @builtin(position) vec4<f32> {
+  exp2_f4f0f1();
+  return vec4<f32>();
+}
+
+@fragment
+fn fragment_main() {
+  exp2_f4f0f1();
+}
+
+@compute @workgroup_size(1)
+fn compute_main() {
+  exp2_f4f0f1();
+}