src/sem: Generate IntrinsicType from intrinsics.def

Add a template file to generate intrinsic_type.h and
intrinsic_type.cc when using tools/intrinsic-gen

Bug: tint:832
Change-Id: I35ddfd497d6ab424dc49a18a9fd7e5eb7f8363b0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52643
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 817f08e..aa4e735 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -463,6 +463,8 @@
     "sem/i32_type.cc",
     "sem/i32_type.h",
     "sem/info.h",
+    "sem/intrinsic_type.cc",
+    "sem/intrinsic_type.h",
     "sem/intrinsic.h",
     "sem/matrix_type.cc",
     "sem/matrix_type.h",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a1c6a05..1b1bd36 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -246,6 +246,8 @@
   sem/function.cc
   sem/info.cc
   sem/info.h
+  sem/intrinsic_type.cc
+  sem/intrinsic_type.h
   sem/intrinsic.cc
   sem/intrinsic.h
   sem/member_accessor_expression.cc
diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc
index 048f12b..bbdc9b4 100644
--- a/src/intrinsic_table.cc
+++ b/src/intrinsic_table.cc
@@ -1056,11 +1056,11 @@
   Register(I::kModf,            f32,         {f32, ptr_f32}                                           ); // NOLINT
   Register(I::kModf,            vecN_f32,    {vecN_f32, ptr_vecN_f32}                                 ); // NOLINT
   Register(I::kNormalize,       vecN_f32,    {vecN_f32}                                               ); // NOLINT
-  Register(I::kPack2x16Float,   u32,         {vec2_f32}                                               ); // NOLINT
-  Register(I::kPack2x16Snorm,   u32,         {vec2_f32}                                               ); // NOLINT
-  Register(I::kPack2x16Unorm,   u32,         {vec2_f32}                                               ); // NOLINT
-  Register(I::kPack4x8Snorm,    u32,         {vec4_f32}                                               ); // NOLINT
-  Register(I::kPack4x8Unorm,    u32,         {vec4_f32}                                               ); // NOLINT
+  Register(I::kPack2x16float,   u32,         {vec2_f32}                                               ); // NOLINT
+  Register(I::kPack2x16snorm,   u32,         {vec2_f32}                                               ); // NOLINT
+  Register(I::kPack2x16unorm,   u32,         {vec2_f32}                                               ); // NOLINT
+  Register(I::kPack4x8snorm,    u32,         {vec4_f32}                                               ); // NOLINT
+  Register(I::kPack4x8unorm,    u32,         {vec4_f32}                                               ); // NOLINT
   Register(I::kPow,             f32,         {f32, f32}                                               ); // NOLINT
   Register(I::kPow,             vecN_f32,    {vecN_f32, vecN_f32}                                     ); // NOLINT
   Register(I::kReflect,         f32,         {f32, f32}                                               ); // NOLINT
@@ -1090,11 +1090,11 @@
   Register(I::kTanh,            vecN_f32,    {vecN_f32}                                               ); // NOLINT
   Register(I::kTrunc,           f32,         {f32}                                                    ); // NOLINT
   Register(I::kTrunc,           vecN_f32,    {vecN_f32}                                               ); // NOLINT
-  Register(I::kUnpack2x16Float, vec2_f32,    {u32}                                                    ); // NOLINT
-  Register(I::kUnpack2x16Snorm, vec2_f32,    {u32}                                                    ); // NOLINT
-  Register(I::kUnpack2x16Unorm, vec2_f32,    {u32}                                                    ); // NOLINT
-  Register(I::kUnpack4x8Snorm,  vec4_f32,    {u32}                                                    ); // NOLINT
-  Register(I::kUnpack4x8Unorm,  vec4_f32,    {u32}                                                    ); // NOLINT
+  Register(I::kUnpack2x16float, vec2_f32,    {u32}                                                    ); // NOLINT
+  Register(I::kUnpack2x16snorm, vec2_f32,    {u32}                                                    ); // NOLINT
+  Register(I::kUnpack2x16unorm, vec2_f32,    {u32}                                                    ); // NOLINT
+  Register(I::kUnpack4x8snorm,  vec4_f32,    {u32}                                                    ); // NOLINT
+  Register(I::kUnpack4x8unorm,  vec4_f32,    {u32}                                                    ); // NOLINT
   Register(I::kWorkgroupBarrier,void_,       {}                                                       ); // NOLINT
   // clang-format on
 
diff --git a/src/intrinsic_table_test.cc b/src/intrinsic_table_test.cc
index 60d2776..df11c66 100644
--- a/src/intrinsic_table_test.cc
+++ b/src/intrinsic_table_test.cc
@@ -59,10 +59,10 @@
   auto* u32 = create<sem::U32>();
   auto* vec2_f32 = create<sem::Vector>(f32, 2);
   auto result =
-      table->Lookup(*this, IntrinsicType::kUnpack2x16Float, {u32}, Source{});
+      table->Lookup(*this, IntrinsicType::kUnpack2x16float, {u32}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
   ASSERT_EQ(result.diagnostics.str(), "");
-  EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kUnpack2x16Float);
+  EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kUnpack2x16float);
   EXPECT_THAT(result.intrinsic->ReturnType(), vec2_f32);
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{u32}));
 }
@@ -70,7 +70,7 @@
 TEST_F(IntrinsicTableTest, MismatchU32) {
   auto* f32 = create<sem::F32>();
   auto result =
-      table->Lookup(*this, IntrinsicType::kUnpack2x16Float, {f32}, Source{});
+      table->Lookup(*this, IntrinsicType::kUnpack2x16float, {f32}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
   ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
diff --git a/src/resolver/intrinsic_test.cc b/src/resolver/intrinsic_test.cc
index 68a1bc0..2633d5f 100644
--- a/src/resolver/intrinsic_test.cc
+++ b/src/resolver/intrinsic_test.cc
@@ -581,8 +581,8 @@
 TEST_P(ResolverIntrinsicTest_DataPacking, InferType) {
   auto param = GetParam();
 
-  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
-               param.intrinsic == IntrinsicType::kPack4x8Unorm;
+  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8snorm ||
+               param.intrinsic == IntrinsicType::kPack4x8unorm;
 
   auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f))
                      : Call(param.name, vec2<f32>(1.f, 2.f));
@@ -596,8 +596,8 @@
 TEST_P(ResolverIntrinsicTest_DataPacking, Error_IncorrectParamType) {
   auto param = GetParam();
 
-  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
-               param.intrinsic == IntrinsicType::kPack4x8Unorm;
+  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8snorm ||
+               param.intrinsic == IntrinsicType::kPack4x8unorm;
 
   auto* call = pack4 ? Call(param.name, vec4<i32>(1, 2, 3, 4))
                      : Call(param.name, vec2<i32>(1, 2));
@@ -624,8 +624,8 @@
 TEST_P(ResolverIntrinsicTest_DataPacking, Error_TooManyParams) {
   auto param = GetParam();
 
-  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8Snorm ||
-               param.intrinsic == IntrinsicType::kPack4x8Unorm;
+  bool pack4 = param.intrinsic == IntrinsicType::kPack4x8snorm ||
+               param.intrinsic == IntrinsicType::kPack4x8unorm;
 
   auto* call = pack4 ? Call(param.name, vec4<f32>(1.f, 2.f, 3.f, 4.f), 1.0f)
                      : Call(param.name, vec2<f32>(1.f, 2.f), 1.0f);
@@ -641,19 +641,19 @@
     ResolverTest,
     ResolverIntrinsicTest_DataPacking,
     testing::Values(
-        IntrinsicData{"pack4x8snorm", IntrinsicType::kPack4x8Snorm},
-        IntrinsicData{"pack4x8unorm", IntrinsicType::kPack4x8Unorm},
-        IntrinsicData{"pack2x16snorm", IntrinsicType::kPack2x16Snorm},
-        IntrinsicData{"pack2x16unorm", IntrinsicType::kPack2x16Unorm},
-        IntrinsicData{"pack2x16float", IntrinsicType::kPack2x16Float}));
+        IntrinsicData{"pack4x8snorm", IntrinsicType::kPack4x8snorm},
+        IntrinsicData{"pack4x8unorm", IntrinsicType::kPack4x8unorm},
+        IntrinsicData{"pack2x16snorm", IntrinsicType::kPack2x16snorm},
+        IntrinsicData{"pack2x16unorm", IntrinsicType::kPack2x16unorm},
+        IntrinsicData{"pack2x16float", IntrinsicType::kPack2x16float}));
 
 using ResolverIntrinsicTest_DataUnpacking =
     ResolverTestWithParam<IntrinsicData>;
 TEST_P(ResolverIntrinsicTest_DataUnpacking, InferType) {
   auto param = GetParam();
 
-  bool pack4 = param.intrinsic == IntrinsicType::kUnpack4x8Snorm ||
-               param.intrinsic == IntrinsicType::kUnpack4x8Unorm;
+  bool pack4 = param.intrinsic == IntrinsicType::kUnpack4x8snorm ||
+               param.intrinsic == IntrinsicType::kUnpack4x8unorm;
 
   auto* call = Call(param.name, 1u);
   WrapInFunction(call);
@@ -672,11 +672,11 @@
     ResolverTest,
     ResolverIntrinsicTest_DataUnpacking,
     testing::Values(
-        IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8Snorm},
-        IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8Unorm},
-        IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16Snorm},
-        IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16Unorm},
-        IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16Float}));
+        IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8snorm},
+        IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8unorm},
+        IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16snorm},
+        IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16unorm},
+        IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16float}));
 
 using ResolverIntrinsicTest_SingleParam = ResolverTestWithParam<IntrinsicData>;
 TEST_P(ResolverIntrinsicTest_SingleParam, Scalar) {
diff --git a/src/sem/intrinsic.cc b/src/sem/intrinsic.cc
index 24260d1..6471f43 100644
--- a/src/sem/intrinsic.cc
+++ b/src/sem/intrinsic.cc
@@ -28,113 +28,6 @@
   return sem::str(type_);
 }
 
-/// Name matches the spelling in the WGSL spec including case.
-#define INTRINSIC_LIST()                                                  \
-  INTRINSIC(IntrinsicType::kNone, "<not-an-intrinsic>")                   \
-  INTRINSIC(IntrinsicType::kAbs, "abs")                                   \
-  INTRINSIC(IntrinsicType::kAcos, "acos")                                 \
-  INTRINSIC(IntrinsicType::kAll, "all")                                   \
-  INTRINSIC(IntrinsicType::kAny, "any")                                   \
-  INTRINSIC(IntrinsicType::kArrayLength, "arrayLength")                   \
-  INTRINSIC(IntrinsicType::kAsin, "asin")                                 \
-  INTRINSIC(IntrinsicType::kAtan, "atan")                                 \
-  INTRINSIC(IntrinsicType::kAtan2, "atan2")                               \
-  INTRINSIC(IntrinsicType::kCeil, "ceil")                                 \
-  INTRINSIC(IntrinsicType::kClamp, "clamp")                               \
-  INTRINSIC(IntrinsicType::kCos, "cos")                                   \
-  INTRINSIC(IntrinsicType::kCosh, "cosh")                                 \
-  INTRINSIC(IntrinsicType::kCountOneBits, "countOneBits")                 \
-  INTRINSIC(IntrinsicType::kCross, "cross")                               \
-  INTRINSIC(IntrinsicType::kDeterminant, "determinant")                   \
-  INTRINSIC(IntrinsicType::kDistance, "distance")                         \
-  INTRINSIC(IntrinsicType::kDot, "dot")                                   \
-  INTRINSIC(IntrinsicType::kDpdx, "dpdx")                                 \
-  INTRINSIC(IntrinsicType::kDpdxCoarse, "dpdxCoarse")                     \
-  INTRINSIC(IntrinsicType::kDpdxFine, "dpdxFine")                         \
-  INTRINSIC(IntrinsicType::kDpdy, "dpdy")                                 \
-  INTRINSIC(IntrinsicType::kDpdyCoarse, "dpdyCoarse")                     \
-  INTRINSIC(IntrinsicType::kDpdyFine, "dpdyFine")                         \
-  INTRINSIC(IntrinsicType::kExp, "exp")                                   \
-  INTRINSIC(IntrinsicType::kExp2, "exp2")                                 \
-  INTRINSIC(IntrinsicType::kFaceForward, "faceForward")                   \
-  INTRINSIC(IntrinsicType::kFloor, "floor")                               \
-  INTRINSIC(IntrinsicType::kFma, "fma")                                   \
-  INTRINSIC(IntrinsicType::kFract, "fract")                               \
-  INTRINSIC(IntrinsicType::kFrexp, "frexp")                               \
-  INTRINSIC(IntrinsicType::kFwidth, "fwidth")                             \
-  INTRINSIC(IntrinsicType::kFwidthCoarse, "fwidthCoarse")                 \
-  INTRINSIC(IntrinsicType::kFwidthFine, "fwidthFine")                     \
-  INTRINSIC(IntrinsicType::kInverseSqrt, "inverseSqrt")                   \
-  INTRINSIC(IntrinsicType::kIsFinite, "isFinite")                         \
-  INTRINSIC(IntrinsicType::kIsInf, "isInf")                               \
-  INTRINSIC(IntrinsicType::kIsNan, "isNan")                               \
-  INTRINSIC(IntrinsicType::kIsNormal, "isNormal")                         \
-  INTRINSIC(IntrinsicType::kLdexp, "ldexp")                               \
-  INTRINSIC(IntrinsicType::kLength, "length")                             \
-  INTRINSIC(IntrinsicType::kLog, "log")                                   \
-  INTRINSIC(IntrinsicType::kLog2, "log2")                                 \
-  INTRINSIC(IntrinsicType::kMax, "max")                                   \
-  INTRINSIC(IntrinsicType::kMin, "min")                                   \
-  INTRINSIC(IntrinsicType::kMix, "mix")                                   \
-  INTRINSIC(IntrinsicType::kModf, "modf")                                 \
-  INTRINSIC(IntrinsicType::kNormalize, "normalize")                       \
-  INTRINSIC(IntrinsicType::kPack4x8Snorm, "pack4x8snorm")                 \
-  INTRINSIC(IntrinsicType::kPack4x8Unorm, "pack4x8unorm")                 \
-  INTRINSIC(IntrinsicType::kPack2x16Snorm, "pack2x16snorm")               \
-  INTRINSIC(IntrinsicType::kPack2x16Unorm, "pack2x16unorm")               \
-  INTRINSIC(IntrinsicType::kPack2x16Float, "pack2x16float")               \
-  INTRINSIC(IntrinsicType::kPow, "pow")                                   \
-  INTRINSIC(IntrinsicType::kReflect, "reflect")                           \
-  INTRINSIC(IntrinsicType::kReverseBits, "reverseBits")                   \
-  INTRINSIC(IntrinsicType::kRound, "round")                               \
-  INTRINSIC(IntrinsicType::kSelect, "select")                             \
-  INTRINSIC(IntrinsicType::kSign, "sign")                                 \
-  INTRINSIC(IntrinsicType::kSin, "sin")                                   \
-  INTRINSIC(IntrinsicType::kSinh, "sinh")                                 \
-  INTRINSIC(IntrinsicType::kSmoothStep, "smoothStep")                     \
-  INTRINSIC(IntrinsicType::kSqrt, "sqrt")                                 \
-  INTRINSIC(IntrinsicType::kStep, "step")                                 \
-  INTRINSIC(IntrinsicType::kStorageBarrier, "storageBarrier")             \
-  INTRINSIC(IntrinsicType::kTan, "tan")                                   \
-  INTRINSIC(IntrinsicType::kTanh, "tanh")                                 \
-  INTRINSIC(IntrinsicType::kTextureDimensions, "textureDimensions")       \
-  INTRINSIC(IntrinsicType::kTextureLoad, "textureLoad")                   \
-  INTRINSIC(IntrinsicType::kTextureNumLayers, "textureNumLayers")         \
-  INTRINSIC(IntrinsicType::kTextureNumLevels, "textureNumLevels")         \
-  INTRINSIC(IntrinsicType::kTextureNumSamples, "textureNumSamples")       \
-  INTRINSIC(IntrinsicType::kTextureSample, "textureSample")               \
-  INTRINSIC(IntrinsicType::kTextureSampleBias, "textureSampleBias")       \
-  INTRINSIC(IntrinsicType::kTextureSampleCompare, "textureSampleCompare") \
-  INTRINSIC(IntrinsicType::kTextureSampleGrad, "textureSampleGrad")       \
-  INTRINSIC(IntrinsicType::kTextureSampleLevel, "textureSampleLevel")     \
-  INTRINSIC(IntrinsicType::kTextureStore, "textureStore")                 \
-  INTRINSIC(IntrinsicType::kTrunc, "trunc")                               \
-  INTRINSIC(IntrinsicType::kUnpack2x16Float, "unpack2x16float")           \
-  INTRINSIC(IntrinsicType::kUnpack2x16Snorm, "unpack2x16snorm")           \
-  INTRINSIC(IntrinsicType::kUnpack2x16Unorm, "unpack2x16unorm")           \
-  INTRINSIC(IntrinsicType::kUnpack4x8Snorm, "unpack4x8snorm")             \
-  INTRINSIC(IntrinsicType::kUnpack4x8Unorm, "unpack4x8unorm")             \
-  INTRINSIC(IntrinsicType::kWorkgroupBarrier, "workgroupBarrier")
-
-IntrinsicType ParseIntrinsicType(const std::string& name) {
-#define INTRINSIC(ENUM, NAME) \
-  if (name == NAME) {         \
-    return ENUM;              \
-  }
-  INTRINSIC_LIST()
-#undef INTRINSIC
-  return IntrinsicType::kNone;
-}
-
-const char* str(IntrinsicType i) {
-#define INTRINSIC(ENUM, NAME) \
-  case ENUM:                  \
-    return NAME;
-  switch (i) { INTRINSIC_LIST() }
-#undef INTRINSIC
-  return "<unknown>";
-}
-
 bool IsCoarseDerivativeIntrinsic(IntrinsicType i) {
   return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse ||
          i == IntrinsicType::kFwidthCoarse;
@@ -174,19 +67,19 @@
 }
 
 bool IsDataPackingIntrinsic(IntrinsicType i) {
-  return i == IntrinsicType::kPack4x8Snorm ||
-         i == IntrinsicType::kPack4x8Unorm ||
-         i == IntrinsicType::kPack2x16Snorm ||
-         i == IntrinsicType::kPack2x16Unorm ||
-         i == IntrinsicType::kPack2x16Float;
+  return i == IntrinsicType::kPack4x8snorm ||
+         i == IntrinsicType::kPack4x8unorm ||
+         i == IntrinsicType::kPack2x16snorm ||
+         i == IntrinsicType::kPack2x16unorm ||
+         i == IntrinsicType::kPack2x16float;
 }
 
 bool IsDataUnpackingIntrinsic(IntrinsicType i) {
-  return i == IntrinsicType::kUnpack4x8Snorm ||
-         i == IntrinsicType::kUnpack4x8Unorm ||
-         i == IntrinsicType::kUnpack2x16Snorm ||
-         i == IntrinsicType::kUnpack2x16Unorm ||
-         i == IntrinsicType::kUnpack2x16Float;
+  return i == IntrinsicType::kUnpack4x8snorm ||
+         i == IntrinsicType::kUnpack4x8unorm ||
+         i == IntrinsicType::kUnpack2x16snorm ||
+         i == IntrinsicType::kUnpack2x16unorm ||
+         i == IntrinsicType::kUnpack2x16float;
 }
 
 bool IsBarrierIntrinsic(IntrinsicType i) {
diff --git a/src/sem/intrinsic.h b/src/sem/intrinsic.h
index a862733..2268680 100644
--- a/src/sem/intrinsic.h
+++ b/src/sem/intrinsic.h
@@ -18,109 +18,11 @@
 #include <string>
 
 #include "src/sem/call_target.h"
+#include "src/sem/intrinsic_type.h"
 
 namespace tint {
 namespace sem {
 
-enum class IntrinsicType {
-  kNone = -1,
-
-  kAbs,
-  kAcos,
-  kAll,
-  kAny,
-  kArrayLength,
-  kAsin,
-  kAtan,
-  kAtan2,
-  kCeil,
-  kClamp,
-  kCos,
-  kCosh,
-  kCountOneBits,
-  kCross,
-  kDeterminant,
-  kDistance,
-  kDot,
-  kDpdx,
-  kDpdxCoarse,
-  kDpdxFine,
-  kDpdy,
-  kDpdyCoarse,
-  kDpdyFine,
-  kExp,
-  kExp2,
-  kFaceForward,
-  kFloor,
-  kFma,
-  kFract,
-  kFrexp,
-  kFwidth,
-  kFwidthCoarse,
-  kFwidthFine,
-  kInverseSqrt,
-  kIsFinite,
-  kIsInf,
-  kIsNan,
-  kIsNormal,
-  kLdexp,
-  kLength,
-  kLog,
-  kLog2,
-  kMax,
-  kMin,
-  kMix,
-  kModf,
-  kNormalize,
-  kPack2x16Float,
-  kPack2x16Snorm,
-  kPack2x16Unorm,
-  kPack4x8Snorm,
-  kPack4x8Unorm,
-  kPow,
-  kReflect,
-  kReverseBits,
-  kRound,
-  kSelect,
-  kSign,
-  kSin,
-  kSinh,
-  kSmoothStep,
-  kSqrt,
-  kStep,
-  kStorageBarrier,
-  kTan,
-  kTanh,
-  kTextureDimensions,
-  kTextureLoad,
-  kTextureNumLayers,
-  kTextureNumLevels,
-  kTextureNumSamples,
-  kTextureSample,
-  kTextureSampleBias,
-  kTextureSampleCompare,
-  kTextureSampleGrad,
-  kTextureSampleLevel,
-  kTextureStore,
-  kTrunc,
-  kUnpack2x16Float,
-  kUnpack2x16Snorm,
-  kUnpack2x16Unorm,
-  kUnpack4x8Snorm,
-  kUnpack4x8Unorm,
-  kWorkgroupBarrier,
-};
-
-/// Matches the IntrisicType by name
-/// @param name the intrinsic name to parse
-/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
-/// match any intrinsic.
-IntrinsicType ParseIntrinsicType(const std::string& name);
-
-/// @returns the name of the intrinsic function type. The spelling, including
-/// case, matches the name in the WGSL spec.
-const char* str(IntrinsicType i);
-
 /// Determines if the given `i` is a coarse derivative
 /// @param i the intrinsic type
 /// @returns true if the given derivative is coarse.
diff --git a/src/sem/intrinsic_test.cc b/src/sem/intrinsic_test.cc
index e35ea5a..e42b6eb 100644
--- a/src/sem/intrinsic_test.cc
+++ b/src/sem/intrinsic_test.cc
@@ -114,11 +114,11 @@
         IntrinsicData{"textureSampleGrad", IntrinsicType::kTextureSampleGrad},
         IntrinsicData{"textureSampleLevel", IntrinsicType::kTextureSampleLevel},
         IntrinsicData{"trunc", IntrinsicType::kTrunc},
-        IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16Float},
-        IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16Snorm},
-        IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16Unorm},
-        IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8Snorm},
-        IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8Unorm},
+        IntrinsicData{"unpack2x16float", IntrinsicType::kUnpack2x16float},
+        IntrinsicData{"unpack2x16snorm", IntrinsicType::kUnpack2x16snorm},
+        IntrinsicData{"unpack2x16unorm", IntrinsicType::kUnpack2x16unorm},
+        IntrinsicData{"unpack4x8snorm", IntrinsicType::kUnpack4x8snorm},
+        IntrinsicData{"unpack4x8unorm", IntrinsicType::kUnpack4x8unorm},
         IntrinsicData{"workgroupBarrier", IntrinsicType::kWorkgroupBarrier}));
 
 TEST_F(IntrinsicTypeTest, ParseNoMatch) {
diff --git a/src/sem/intrinsic_type.cc b/src/sem/intrinsic_type.cc
new file mode 100644
index 0000000..727a57c
--- /dev/null
+++ b/src/sem/intrinsic_type.cc
@@ -0,0 +1,458 @@
+// Copyright 2021 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/intrinsic-gen
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/sem/intrinsic_type.h"
+
+namespace tint {
+namespace sem {
+
+IntrinsicType ParseIntrinsicType(const std::string& name) {
+  if (name == "abs") {
+    return IntrinsicType::kAbs;
+  }
+  if (name == "acos") {
+    return IntrinsicType::kAcos;
+  }
+  if (name == "all") {
+    return IntrinsicType::kAll;
+  }
+  if (name == "any") {
+    return IntrinsicType::kAny;
+  }
+  if (name == "arrayLength") {
+    return IntrinsicType::kArrayLength;
+  }
+  if (name == "asin") {
+    return IntrinsicType::kAsin;
+  }
+  if (name == "atan") {
+    return IntrinsicType::kAtan;
+  }
+  if (name == "atan2") {
+    return IntrinsicType::kAtan2;
+  }
+  if (name == "ceil") {
+    return IntrinsicType::kCeil;
+  }
+  if (name == "clamp") {
+    return IntrinsicType::kClamp;
+  }
+  if (name == "cos") {
+    return IntrinsicType::kCos;
+  }
+  if (name == "cosh") {
+    return IntrinsicType::kCosh;
+  }
+  if (name == "countOneBits") {
+    return IntrinsicType::kCountOneBits;
+  }
+  if (name == "cross") {
+    return IntrinsicType::kCross;
+  }
+  if (name == "determinant") {
+    return IntrinsicType::kDeterminant;
+  }
+  if (name == "distance") {
+    return IntrinsicType::kDistance;
+  }
+  if (name == "dot") {
+    return IntrinsicType::kDot;
+  }
+  if (name == "dpdx") {
+    return IntrinsicType::kDpdx;
+  }
+  if (name == "dpdxCoarse") {
+    return IntrinsicType::kDpdxCoarse;
+  }
+  if (name == "dpdxFine") {
+    return IntrinsicType::kDpdxFine;
+  }
+  if (name == "dpdy") {
+    return IntrinsicType::kDpdy;
+  }
+  if (name == "dpdyCoarse") {
+    return IntrinsicType::kDpdyCoarse;
+  }
+  if (name == "dpdyFine") {
+    return IntrinsicType::kDpdyFine;
+  }
+  if (name == "exp") {
+    return IntrinsicType::kExp;
+  }
+  if (name == "exp2") {
+    return IntrinsicType::kExp2;
+  }
+  if (name == "faceForward") {
+    return IntrinsicType::kFaceForward;
+  }
+  if (name == "floor") {
+    return IntrinsicType::kFloor;
+  }
+  if (name == "fma") {
+    return IntrinsicType::kFma;
+  }
+  if (name == "fract") {
+    return IntrinsicType::kFract;
+  }
+  if (name == "frexp") {
+    return IntrinsicType::kFrexp;
+  }
+  if (name == "fwidth") {
+    return IntrinsicType::kFwidth;
+  }
+  if (name == "fwidthCoarse") {
+    return IntrinsicType::kFwidthCoarse;
+  }
+  if (name == "fwidthFine") {
+    return IntrinsicType::kFwidthFine;
+  }
+  if (name == "inverseSqrt") {
+    return IntrinsicType::kInverseSqrt;
+  }
+  if (name == "isFinite") {
+    return IntrinsicType::kIsFinite;
+  }
+  if (name == "isInf") {
+    return IntrinsicType::kIsInf;
+  }
+  if (name == "isNan") {
+    return IntrinsicType::kIsNan;
+  }
+  if (name == "isNormal") {
+    return IntrinsicType::kIsNormal;
+  }
+  if (name == "ldexp") {
+    return IntrinsicType::kLdexp;
+  }
+  if (name == "length") {
+    return IntrinsicType::kLength;
+  }
+  if (name == "log") {
+    return IntrinsicType::kLog;
+  }
+  if (name == "log2") {
+    return IntrinsicType::kLog2;
+  }
+  if (name == "max") {
+    return IntrinsicType::kMax;
+  }
+  if (name == "min") {
+    return IntrinsicType::kMin;
+  }
+  if (name == "mix") {
+    return IntrinsicType::kMix;
+  }
+  if (name == "modf") {
+    return IntrinsicType::kModf;
+  }
+  if (name == "normalize") {
+    return IntrinsicType::kNormalize;
+  }
+  if (name == "pack2x16float") {
+    return IntrinsicType::kPack2x16float;
+  }
+  if (name == "pack2x16snorm") {
+    return IntrinsicType::kPack2x16snorm;
+  }
+  if (name == "pack2x16unorm") {
+    return IntrinsicType::kPack2x16unorm;
+  }
+  if (name == "pack4x8snorm") {
+    return IntrinsicType::kPack4x8snorm;
+  }
+  if (name == "pack4x8unorm") {
+    return IntrinsicType::kPack4x8unorm;
+  }
+  if (name == "pow") {
+    return IntrinsicType::kPow;
+  }
+  if (name == "reflect") {
+    return IntrinsicType::kReflect;
+  }
+  if (name == "reverseBits") {
+    return IntrinsicType::kReverseBits;
+  }
+  if (name == "round") {
+    return IntrinsicType::kRound;
+  }
+  if (name == "select") {
+    return IntrinsicType::kSelect;
+  }
+  if (name == "sign") {
+    return IntrinsicType::kSign;
+  }
+  if (name == "sin") {
+    return IntrinsicType::kSin;
+  }
+  if (name == "sinh") {
+    return IntrinsicType::kSinh;
+  }
+  if (name == "smoothStep") {
+    return IntrinsicType::kSmoothStep;
+  }
+  if (name == "sqrt") {
+    return IntrinsicType::kSqrt;
+  }
+  if (name == "step") {
+    return IntrinsicType::kStep;
+  }
+  if (name == "storageBarrier") {
+    return IntrinsicType::kStorageBarrier;
+  }
+  if (name == "tan") {
+    return IntrinsicType::kTan;
+  }
+  if (name == "tanh") {
+    return IntrinsicType::kTanh;
+  }
+  if (name == "trunc") {
+    return IntrinsicType::kTrunc;
+  }
+  if (name == "unpack2x16float") {
+    return IntrinsicType::kUnpack2x16float;
+  }
+  if (name == "unpack2x16snorm") {
+    return IntrinsicType::kUnpack2x16snorm;
+  }
+  if (name == "unpack2x16unorm") {
+    return IntrinsicType::kUnpack2x16unorm;
+  }
+  if (name == "unpack4x8snorm") {
+    return IntrinsicType::kUnpack4x8snorm;
+  }
+  if (name == "unpack4x8unorm") {
+    return IntrinsicType::kUnpack4x8unorm;
+  }
+  if (name == "workgroupBarrier") {
+    return IntrinsicType::kWorkgroupBarrier;
+  }
+  if (name == "textureDimensions") {
+    return IntrinsicType::kTextureDimensions;
+  }
+  if (name == "textureNumLayers") {
+    return IntrinsicType::kTextureNumLayers;
+  }
+  if (name == "textureNumLevels") {
+    return IntrinsicType::kTextureNumLevels;
+  }
+  if (name == "textureNumSamples") {
+    return IntrinsicType::kTextureNumSamples;
+  }
+  if (name == "textureSample") {
+    return IntrinsicType::kTextureSample;
+  }
+  if (name == "textureSampleBias") {
+    return IntrinsicType::kTextureSampleBias;
+  }
+  if (name == "textureSampleCompare") {
+    return IntrinsicType::kTextureSampleCompare;
+  }
+  if (name == "textureSampleGrad") {
+    return IntrinsicType::kTextureSampleGrad;
+  }
+  if (name == "textureSampleLevel") {
+    return IntrinsicType::kTextureSampleLevel;
+  }
+  if (name == "textureStore") {
+    return IntrinsicType::kTextureStore;
+  }
+  if (name == "textureLoad") {
+    return IntrinsicType::kTextureLoad;
+  }
+  return IntrinsicType::kNone;
+}
+
+const char* str(IntrinsicType i) {
+  switch (i) {
+    case IntrinsicType::kNone:
+      return "<none>";
+    case IntrinsicType::kAbs:
+      return "abs";
+    case IntrinsicType::kAcos:
+      return "acos";
+    case IntrinsicType::kAll:
+      return "all";
+    case IntrinsicType::kAny:
+      return "any";
+    case IntrinsicType::kArrayLength:
+      return "arrayLength";
+    case IntrinsicType::kAsin:
+      return "asin";
+    case IntrinsicType::kAtan:
+      return "atan";
+    case IntrinsicType::kAtan2:
+      return "atan2";
+    case IntrinsicType::kCeil:
+      return "ceil";
+    case IntrinsicType::kClamp:
+      return "clamp";
+    case IntrinsicType::kCos:
+      return "cos";
+    case IntrinsicType::kCosh:
+      return "cosh";
+    case IntrinsicType::kCountOneBits:
+      return "countOneBits";
+    case IntrinsicType::kCross:
+      return "cross";
+    case IntrinsicType::kDeterminant:
+      return "determinant";
+    case IntrinsicType::kDistance:
+      return "distance";
+    case IntrinsicType::kDot:
+      return "dot";
+    case IntrinsicType::kDpdx:
+      return "dpdx";
+    case IntrinsicType::kDpdxCoarse:
+      return "dpdxCoarse";
+    case IntrinsicType::kDpdxFine:
+      return "dpdxFine";
+    case IntrinsicType::kDpdy:
+      return "dpdy";
+    case IntrinsicType::kDpdyCoarse:
+      return "dpdyCoarse";
+    case IntrinsicType::kDpdyFine:
+      return "dpdyFine";
+    case IntrinsicType::kExp:
+      return "exp";
+    case IntrinsicType::kExp2:
+      return "exp2";
+    case IntrinsicType::kFaceForward:
+      return "faceForward";
+    case IntrinsicType::kFloor:
+      return "floor";
+    case IntrinsicType::kFma:
+      return "fma";
+    case IntrinsicType::kFract:
+      return "fract";
+    case IntrinsicType::kFrexp:
+      return "frexp";
+    case IntrinsicType::kFwidth:
+      return "fwidth";
+    case IntrinsicType::kFwidthCoarse:
+      return "fwidthCoarse";
+    case IntrinsicType::kFwidthFine:
+      return "fwidthFine";
+    case IntrinsicType::kInverseSqrt:
+      return "inverseSqrt";
+    case IntrinsicType::kIsFinite:
+      return "isFinite";
+    case IntrinsicType::kIsInf:
+      return "isInf";
+    case IntrinsicType::kIsNan:
+      return "isNan";
+    case IntrinsicType::kIsNormal:
+      return "isNormal";
+    case IntrinsicType::kLdexp:
+      return "ldexp";
+    case IntrinsicType::kLength:
+      return "length";
+    case IntrinsicType::kLog:
+      return "log";
+    case IntrinsicType::kLog2:
+      return "log2";
+    case IntrinsicType::kMax:
+      return "max";
+    case IntrinsicType::kMin:
+      return "min";
+    case IntrinsicType::kMix:
+      return "mix";
+    case IntrinsicType::kModf:
+      return "modf";
+    case IntrinsicType::kNormalize:
+      return "normalize";
+    case IntrinsicType::kPack2x16float:
+      return "pack2x16float";
+    case IntrinsicType::kPack2x16snorm:
+      return "pack2x16snorm";
+    case IntrinsicType::kPack2x16unorm:
+      return "pack2x16unorm";
+    case IntrinsicType::kPack4x8snorm:
+      return "pack4x8snorm";
+    case IntrinsicType::kPack4x8unorm:
+      return "pack4x8unorm";
+    case IntrinsicType::kPow:
+      return "pow";
+    case IntrinsicType::kReflect:
+      return "reflect";
+    case IntrinsicType::kReverseBits:
+      return "reverseBits";
+    case IntrinsicType::kRound:
+      return "round";
+    case IntrinsicType::kSelect:
+      return "select";
+    case IntrinsicType::kSign:
+      return "sign";
+    case IntrinsicType::kSin:
+      return "sin";
+    case IntrinsicType::kSinh:
+      return "sinh";
+    case IntrinsicType::kSmoothStep:
+      return "smoothStep";
+    case IntrinsicType::kSqrt:
+      return "sqrt";
+    case IntrinsicType::kStep:
+      return "step";
+    case IntrinsicType::kStorageBarrier:
+      return "storageBarrier";
+    case IntrinsicType::kTan:
+      return "tan";
+    case IntrinsicType::kTanh:
+      return "tanh";
+    case IntrinsicType::kTrunc:
+      return "trunc";
+    case IntrinsicType::kUnpack2x16float:
+      return "unpack2x16float";
+    case IntrinsicType::kUnpack2x16snorm:
+      return "unpack2x16snorm";
+    case IntrinsicType::kUnpack2x16unorm:
+      return "unpack2x16unorm";
+    case IntrinsicType::kUnpack4x8snorm:
+      return "unpack4x8snorm";
+    case IntrinsicType::kUnpack4x8unorm:
+      return "unpack4x8unorm";
+    case IntrinsicType::kWorkgroupBarrier:
+      return "workgroupBarrier";
+    case IntrinsicType::kTextureDimensions:
+      return "textureDimensions";
+    case IntrinsicType::kTextureNumLayers:
+      return "textureNumLayers";
+    case IntrinsicType::kTextureNumLevels:
+      return "textureNumLevels";
+    case IntrinsicType::kTextureNumSamples:
+      return "textureNumSamples";
+    case IntrinsicType::kTextureSample:
+      return "textureSample";
+    case IntrinsicType::kTextureSampleBias:
+      return "textureSampleBias";
+    case IntrinsicType::kTextureSampleCompare:
+      return "textureSampleCompare";
+    case IntrinsicType::kTextureSampleGrad:
+      return "textureSampleGrad";
+    case IntrinsicType::kTextureSampleLevel:
+      return "textureSampleLevel";
+    case IntrinsicType::kTextureStore:
+      return "textureStore";
+    case IntrinsicType::kTextureLoad:
+      return "textureLoad";
+  }
+  return "<unknown>";
+}
+
+}  // namespace sem
+}  // namespace tint
diff --git a/src/sem/intrinsic_type.cc.tmpl b/src/sem/intrinsic_type.cc.tmpl
new file mode 100644
index 0000000..e4059e3
--- /dev/null
+++ b/src/sem/intrinsic_type.cc.tmpl
@@ -0,0 +1,38 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/intrinsic-gen to generate intrinsic_type.cc
+
+See:
+* tools/cmd/intrinsic-gen/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+#include "src/sem/intrinsic_type.h"
+
+namespace tint {
+namespace sem {
+
+IntrinsicType ParseIntrinsicType(const std::string& name) {
+{{- range .Sem.Functions  }}
+  if (name == "{{.Name}}") {
+    return IntrinsicType::k{{Title .Name}};
+  }
+{{- end  }}
+  return IntrinsicType::kNone;
+}
+
+const char* str(IntrinsicType i) {
+  switch (i) {
+    case IntrinsicType::kNone:
+      return "<none>";
+{{- range .Sem.Functions  }}
+    case IntrinsicType::k{{Title .Name}}:
+      return "{{.Name}}";
+{{- end  }}
+  }
+  return "<unknown>";
+}
+
+}  // namespace sem
+}  // namespace tint
diff --git a/src/sem/intrinsic_type.h b/src/sem/intrinsic_type.h
new file mode 100644
index 0000000..c8c02dc
--- /dev/null
+++ b/src/sem/intrinsic_type.h
@@ -0,0 +1,130 @@
+// Copyright 2021 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/intrinsic-gen
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SRC_SEM_INTRINSIC_TYPE_H_
+#define SRC_SEM_INTRINSIC_TYPE_H_
+
+#include <string>
+
+namespace tint {
+namespace sem {
+
+/// Enumerator of all intrinsic functions
+enum class IntrinsicType {
+  kNone = -1,
+  kAbs,
+  kAcos,
+  kAll,
+  kAny,
+  kArrayLength,
+  kAsin,
+  kAtan,
+  kAtan2,
+  kCeil,
+  kClamp,
+  kCos,
+  kCosh,
+  kCountOneBits,
+  kCross,
+  kDeterminant,
+  kDistance,
+  kDot,
+  kDpdx,
+  kDpdxCoarse,
+  kDpdxFine,
+  kDpdy,
+  kDpdyCoarse,
+  kDpdyFine,
+  kExp,
+  kExp2,
+  kFaceForward,
+  kFloor,
+  kFma,
+  kFract,
+  kFrexp,
+  kFwidth,
+  kFwidthCoarse,
+  kFwidthFine,
+  kInverseSqrt,
+  kIsFinite,
+  kIsInf,
+  kIsNan,
+  kIsNormal,
+  kLdexp,
+  kLength,
+  kLog,
+  kLog2,
+  kMax,
+  kMin,
+  kMix,
+  kModf,
+  kNormalize,
+  kPack2x16float,
+  kPack2x16snorm,
+  kPack2x16unorm,
+  kPack4x8snorm,
+  kPack4x8unorm,
+  kPow,
+  kReflect,
+  kReverseBits,
+  kRound,
+  kSelect,
+  kSign,
+  kSin,
+  kSinh,
+  kSmoothStep,
+  kSqrt,
+  kStep,
+  kStorageBarrier,
+  kTan,
+  kTanh,
+  kTrunc,
+  kUnpack2x16float,
+  kUnpack2x16snorm,
+  kUnpack2x16unorm,
+  kUnpack4x8snorm,
+  kUnpack4x8unorm,
+  kWorkgroupBarrier,
+  kTextureDimensions,
+  kTextureNumLayers,
+  kTextureNumLevels,
+  kTextureNumSamples,
+  kTextureSample,
+  kTextureSampleBias,
+  kTextureSampleCompare,
+  kTextureSampleGrad,
+  kTextureSampleLevel,
+  kTextureStore,
+  kTextureLoad,
+};
+
+/// Matches the IntrinsicType by name
+/// @param name the intrinsic name to parse
+/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
+/// match any intrinsic.
+IntrinsicType ParseIntrinsicType(const std::string& name);
+
+/// @returns the name of the intrinsic function type. The spelling, including
+/// case, matches the name in the WGSL spec.
+const char* str(IntrinsicType i);
+
+}  // namespace sem
+}  // namespace tint
+
+#endif  // SRC_SEM_INTRINSIC_TYPE_H_
diff --git a/src/sem/intrinsic_type.h.tmpl b/src/sem/intrinsic_type.h.tmpl
new file mode 100644
index 0000000..8882645
--- /dev/null
+++ b/src/sem/intrinsic_type.h.tmpl
@@ -0,0 +1,40 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/intrinsic-gen to generate intrinsic_type.h
+
+See:
+* tools/cmd/intrinsic-gen/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+#ifndef SRC_SEM_INTRINSIC_TYPE_H_
+#define SRC_SEM_INTRINSIC_TYPE_H_
+
+#include <string>
+
+namespace tint {
+namespace sem {
+
+/// Enumerator of all intrinsic functions
+enum class IntrinsicType {
+  kNone = -1,
+{{- range .Sem.Functions }}
+  k{{Title .Name}},
+{{- end }}
+};
+
+/// Matches the IntrinsicType by name
+/// @param name the intrinsic name to parse
+/// @returns the parsed IntrinsicType, or IntrinsicType::kNone if `name` did not
+/// match any intrinsic.
+IntrinsicType ParseIntrinsicType(const std::string& name);
+
+/// @returns the name of the intrinsic function type. The spelling, including
+/// case, matches the name in the WGSL spec.
+const char* str(IntrinsicType i);
+
+}  // namespace sem
+}  // namespace tint
+
+#endif  // SRC_SEM_INTRINSIC_TYPE_H_
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index b6aa276..aeb2258 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -689,21 +689,21 @@
   uint32_t dims = 2;
   bool is_signed = false;
   uint32_t scale = 65535;
-  if (intrinsic->Type() == sem::IntrinsicType::kPack4x8Snorm ||
-      intrinsic->Type() == sem::IntrinsicType::kPack4x8Unorm) {
+  if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
+      intrinsic->Type() == sem::IntrinsicType::kPack4x8unorm) {
     dims = 4;
     scale = 255;
   }
-  if (intrinsic->Type() == sem::IntrinsicType::kPack4x8Snorm ||
-      intrinsic->Type() == sem::IntrinsicType::kPack2x16Snorm) {
+  if (intrinsic->Type() == sem::IntrinsicType::kPack4x8snorm ||
+      intrinsic->Type() == sem::IntrinsicType::kPack2x16snorm) {
     is_signed = true;
     scale = (scale - 1) / 2;
   }
   switch (intrinsic->Type()) {
-    case sem::IntrinsicType::kPack4x8Snorm:
-    case sem::IntrinsicType::kPack4x8Unorm:
-    case sem::IntrinsicType::kPack2x16Snorm:
-    case sem::IntrinsicType::kPack2x16Unorm:
+    case sem::IntrinsicType::kPack4x8snorm:
+    case sem::IntrinsicType::kPack4x8unorm:
+    case sem::IntrinsicType::kPack2x16snorm:
+    case sem::IntrinsicType::kPack2x16unorm:
       pre << (is_signed ? "" : "u") << "int" << dims << " " << tmp_name << " = "
           << (is_signed ? "" : "u") << "int" << dims << "(round(clamp("
           << expr_out.str() << ", " << (is_signed ? "-1.0" : "0.0")
@@ -722,7 +722,7 @@
       }
       out << ")";
       break;
-    case sem::IntrinsicType::kPack2x16Float:
+    case sem::IntrinsicType::kPack2x16float:
       pre << "uint2 " << tmp_name << " = f32tof16(" << expr_out.str() << ");\n";
       out << "(" << tmp_name << ".x | " << tmp_name << ".y << 16)";
       break;
@@ -748,19 +748,19 @@
   uint32_t dims = 2;
   bool is_signed = false;
   uint32_t scale = 65535;
-  if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8Snorm ||
-      intrinsic->Type() == sem::IntrinsicType::kUnpack4x8Unorm) {
+  if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
+      intrinsic->Type() == sem::IntrinsicType::kUnpack4x8unorm) {
     dims = 4;
     scale = 255;
   }
-  if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8Snorm ||
-      intrinsic->Type() == sem::IntrinsicType::kUnpack2x16Snorm) {
+  if (intrinsic->Type() == sem::IntrinsicType::kUnpack4x8snorm ||
+      intrinsic->Type() == sem::IntrinsicType::kUnpack2x16snorm) {
     is_signed = true;
     scale = (scale - 1) / 2;
   }
   switch (intrinsic->Type()) {
-    case sem::IntrinsicType::kUnpack4x8Snorm:
-    case sem::IntrinsicType::kUnpack2x16Snorm: {
+    case sem::IntrinsicType::kUnpack4x8snorm:
+    case sem::IntrinsicType::kUnpack2x16snorm: {
       auto tmp_name2 = generate_name(kTempNamePrefix);
       pre << "int " << tmp_name2 << " = int(" << expr_out.str() << ");\n";
       // Perform sign extension on the converted values.
@@ -776,8 +776,8 @@
           << ".0, " << (is_signed ? "-1.0" : "0.0") << ", 1.0)";
       break;
     }
-    case sem::IntrinsicType::kUnpack4x8Unorm:
-    case sem::IntrinsicType::kUnpack2x16Unorm: {
+    case sem::IntrinsicType::kUnpack4x8unorm:
+    case sem::IntrinsicType::kUnpack2x16unorm: {
       auto tmp_name2 = generate_name(kTempNamePrefix);
       pre << "uint " << tmp_name2 << " = " << expr_out.str() << ";\n";
       pre << "uint" << dims << " " << tmp_name << " = uint" << dims << "(";
@@ -792,7 +792,7 @@
       out << "float" << dims << "(" << tmp_name << ") / " << scale << ".0";
       break;
     }
-    case sem::IntrinsicType::kUnpack2x16Float:
+    case sem::IntrinsicType::kUnpack2x16float:
       pre << "uint " << tmp_name << " = " << expr_out.str() << ";\n";
       out << "f16tof32(uint2(" << tmp_name << " & 0xffff, " << tmp_name
           << " >> 16))";
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 40e1e16..00ff69f 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -327,10 +327,10 @@
     if (intrinsic->IsTexture()) {
       return EmitTextureCall(expr, intrinsic);
     }
-    if (intrinsic->Type() == sem::IntrinsicType::kPack2x16Float ||
-        intrinsic->Type() == sem::IntrinsicType::kUnpack2x16Float) {
+    if (intrinsic->Type() == sem::IntrinsicType::kPack2x16float ||
+        intrinsic->Type() == sem::IntrinsicType::kUnpack2x16float) {
       make_indent();
-      if (intrinsic->Type() == sem::IntrinsicType::kPack2x16Float) {
+      if (intrinsic->Type() == sem::IntrinsicType::kPack2x16float) {
         out_ << "as_type<uint>(half2(";
       } else {
         out_ << "float2(as_type<half2>(";
@@ -775,16 +775,16 @@
     case sem::IntrinsicType::kFaceForward:
       out += "faceforward";
       break;
-    case sem::IntrinsicType::kPack4x8Snorm:
+    case sem::IntrinsicType::kPack4x8snorm:
       out += "pack_float_to_snorm4x8";
       break;
-    case sem::IntrinsicType::kPack4x8Unorm:
+    case sem::IntrinsicType::kPack4x8unorm:
       out += "pack_float_to_unorm4x8";
       break;
-    case sem::IntrinsicType::kPack2x16Snorm:
+    case sem::IntrinsicType::kPack2x16snorm:
       out += "pack_float_to_snorm2x16";
       break;
-    case sem::IntrinsicType::kPack2x16Unorm:
+    case sem::IntrinsicType::kPack2x16unorm:
       out += "pack_float_to_unorm2x16";
       break;
     case sem::IntrinsicType::kReverseBits:
@@ -799,16 +799,16 @@
     case sem::IntrinsicType::kInverseSqrt:
       out += "rsqrt";
       break;
-    case sem::IntrinsicType::kUnpack4x8Snorm:
+    case sem::IntrinsicType::kUnpack4x8snorm:
       out += "unpack_snorm4x8_to_float";
       break;
-    case sem::IntrinsicType::kUnpack4x8Unorm:
+    case sem::IntrinsicType::kUnpack4x8unorm:
       out += "unpack_unorm4x8_to_float";
       break;
-    case sem::IntrinsicType::kUnpack2x16Snorm:
+    case sem::IntrinsicType::kUnpack2x16snorm:
       out += "unpack_snorm2x16_to_float";
       break;
-    case sem::IntrinsicType::kUnpack2x16Unorm:
+    case sem::IntrinsicType::kUnpack2x16unorm:
       out += "unpack_unorm2x16_to_float";
       break;
     default:
diff --git a/src/writer/msl/generator_impl_intrinsic_test.cc b/src/writer/msl/generator_impl_intrinsic_test.cc
index 5d818f4..65d3ca5 100644
--- a/src/writer/msl/generator_impl_intrinsic_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_test.cc
@@ -143,16 +143,16 @@
       return builder->Call(str.str(), "f2", "f2", "b2");
     case IntrinsicType::kDeterminant:
       return builder->Call(str.str(), "m2x2");
-    case IntrinsicType::kPack2x16Snorm:
-    case IntrinsicType::kPack2x16Unorm:
+    case IntrinsicType::kPack2x16snorm:
+    case IntrinsicType::kPack2x16unorm:
       return builder->Call(str.str(), "f2");
-    case IntrinsicType::kPack4x8Snorm:
-    case IntrinsicType::kPack4x8Unorm:
+    case IntrinsicType::kPack4x8snorm:
+    case IntrinsicType::kPack4x8unorm:
       return builder->Call(str.str(), "f4");
-    case IntrinsicType::kUnpack4x8Snorm:
-    case IntrinsicType::kUnpack4x8Unorm:
-    case IntrinsicType::kUnpack2x16Snorm:
-    case IntrinsicType::kUnpack2x16Unorm:
+    case IntrinsicType::kUnpack4x8snorm:
+    case IntrinsicType::kUnpack4x8unorm:
+    case IntrinsicType::kUnpack2x16snorm:
+    case IntrinsicType::kUnpack2x16unorm:
       return builder->Call(str.str(), "u1");
     case IntrinsicType::kWorkgroupBarrier:
       return builder->Call(str.str());
@@ -243,13 +243,13 @@
         IntrinsicData{IntrinsicType::kMin, ParamType::kF32, "fmin"},
         IntrinsicData{IntrinsicType::kMin, ParamType::kU32, "min"},
         IntrinsicData{IntrinsicType::kNormalize, ParamType::kF32, "normalize"},
-        IntrinsicData{IntrinsicType::kPack4x8Snorm, ParamType::kF32,
+        IntrinsicData{IntrinsicType::kPack4x8snorm, ParamType::kF32,
                       "pack_float_to_snorm4x8"},
-        IntrinsicData{IntrinsicType::kPack4x8Unorm, ParamType::kF32,
+        IntrinsicData{IntrinsicType::kPack4x8unorm, ParamType::kF32,
                       "pack_float_to_unorm4x8"},
-        IntrinsicData{IntrinsicType::kPack2x16Snorm, ParamType::kF32,
+        IntrinsicData{IntrinsicType::kPack2x16snorm, ParamType::kF32,
                       "pack_float_to_snorm2x16"},
-        IntrinsicData{IntrinsicType::kPack2x16Unorm, ParamType::kF32,
+        IntrinsicData{IntrinsicType::kPack2x16unorm, ParamType::kF32,
                       "pack_float_to_unorm2x16"},
         IntrinsicData{IntrinsicType::kPow, ParamType::kF32, "pow"},
         IntrinsicData{IntrinsicType::kReflect, ParamType::kF32, "reflect"},
@@ -267,13 +267,13 @@
         IntrinsicData{IntrinsicType::kTan, ParamType::kF32, "tan"},
         IntrinsicData{IntrinsicType::kTanh, ParamType::kF32, "tanh"},
         IntrinsicData{IntrinsicType::kTrunc, ParamType::kF32, "trunc"},
-        IntrinsicData{IntrinsicType::kUnpack4x8Snorm, ParamType::kU32,
+        IntrinsicData{IntrinsicType::kUnpack4x8snorm, ParamType::kU32,
                       "unpack_snorm4x8_to_float"},
-        IntrinsicData{IntrinsicType::kUnpack4x8Unorm, ParamType::kU32,
+        IntrinsicData{IntrinsicType::kUnpack4x8unorm, ParamType::kU32,
                       "unpack_unorm4x8_to_float"},
-        IntrinsicData{IntrinsicType::kUnpack2x16Snorm, ParamType::kU32,
+        IntrinsicData{IntrinsicType::kUnpack2x16snorm, ParamType::kU32,
                       "unpack_snorm2x16_to_float"},
-        IntrinsicData{IntrinsicType::kUnpack2x16Unorm, ParamType::kU32,
+        IntrinsicData{IntrinsicType::kUnpack2x16unorm, ParamType::kU32,
                       "unpack_unorm2x16_to_float"}));
 
 TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index bb45f2d..c400293 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -185,15 +185,15 @@
       return GLSLstd450Modf;
     case IntrinsicType::kNormalize:
       return GLSLstd450Normalize;
-    case IntrinsicType::kPack4x8Snorm:
+    case IntrinsicType::kPack4x8snorm:
       return GLSLstd450PackSnorm4x8;
-    case IntrinsicType::kPack4x8Unorm:
+    case IntrinsicType::kPack4x8unorm:
       return GLSLstd450PackUnorm4x8;
-    case IntrinsicType::kPack2x16Snorm:
+    case IntrinsicType::kPack2x16snorm:
       return GLSLstd450PackSnorm2x16;
-    case IntrinsicType::kPack2x16Unorm:
+    case IntrinsicType::kPack2x16unorm:
       return GLSLstd450PackUnorm2x16;
-    case IntrinsicType::kPack2x16Float:
+    case IntrinsicType::kPack2x16float:
       return GLSLstd450PackHalf2x16;
     case IntrinsicType::kPow:
       return GLSLstd450Pow;
@@ -219,15 +219,15 @@
       return GLSLstd450Tanh;
     case IntrinsicType::kTrunc:
       return GLSLstd450Trunc;
-    case IntrinsicType::kUnpack4x8Snorm:
+    case IntrinsicType::kUnpack4x8snorm:
       return GLSLstd450UnpackSnorm4x8;
-    case IntrinsicType::kUnpack4x8Unorm:
+    case IntrinsicType::kUnpack4x8unorm:
       return GLSLstd450UnpackUnorm4x8;
-    case IntrinsicType::kUnpack2x16Snorm:
+    case IntrinsicType::kUnpack2x16snorm:
       return GLSLstd450UnpackSnorm2x16;
-    case IntrinsicType::kUnpack2x16Unorm:
+    case IntrinsicType::kUnpack2x16unorm:
       return GLSLstd450UnpackUnorm2x16;
-    case IntrinsicType::kUnpack2x16Float:
+    case IntrinsicType::kUnpack2x16float:
       return GLSLstd450UnpackHalf2x16;
     default:
       break;