Move to version 1.4 of SPIR-V.
diff --git a/include/spirv/unified1/spirv.core.grammar.json b/include/spirv/unified1/spirv.core.grammar.json
index c6736d7..b81d29f 100644
--- a/include/spirv/unified1/spirv.core.grammar.json
+++ b/include/spirv/unified1/spirv.core.grammar.json
@@ -26,7 +26,7 @@
   ],
   "magic_number" : "0x07230203",
   "major_version" : 1,
-  "minor_version" : 3,
+  "minor_version" : 4,
   "revision" : 1,
   "instructions" : [
     {
@@ -519,6 +519,7 @@
       "operands" : [
         { "kind" : "IdRef",                            "name" : "'Target'" },
         { "kind" : "IdRef",                            "name" : "'Source'" },
+        { "kind" : "MemoryAccess", "quantifier" : "?" },
         { "kind" : "MemoryAccess", "quantifier" : "?" }
       ]
     },
@@ -529,6 +530,7 @@
         { "kind" : "IdRef",                            "name" : "'Target'" },
         { "kind" : "IdRef",                            "name" : "'Source'" },
         { "kind" : "IdRef",                            "name" : "'Size'" },
+        { "kind" : "MemoryAccess", "quantifier" : "?" },
         { "kind" : "MemoryAccess", "quantifier" : "?" }
       ],
       "capabilities" : [ "Addresses" ]
@@ -2100,7 +2102,8 @@
         { "kind" : "IdRef",             "name" : "'Value'" },
         { "kind" : "IdRef",             "name" : "'Comparator'" }
       ],
-      "capabilities" : [ "Kernel" ]
+      "capabilities" : [ "Kernel" ],
+      "lastVersion" : "1.3"
     },
     {
       "opname" : "OpAtomicIIncrement",
@@ -3606,6 +3609,50 @@
       "version" : "1.3"
     },
     {
+      "opname" : "OpCopyLogical",
+      "opcode" : 400,
+      "operands" : [
+        { "kind" : "IdResultType" },
+        { "kind" : "IdResult" },
+        { "kind" : "IdRef",        "name" : "'Operand'" }
+      ],
+      "version" : "1.4"
+    },
+    {
+      "opname" : "OpPtrEqual",
+      "opcode" : 401,
+      "operands" : [
+        { "kind" : "IdResultType" },
+        { "kind" : "IdResult" },
+        { "kind" : "IdRef",        "name" : "'Operand 1'" },
+        { "kind" : "IdRef",        "name" : "'Operand 2'" }
+      ],
+      "version" : "1.4"
+    },
+    {
+      "opname" : "OpPtrNotEqual",
+      "opcode" : 402,
+      "operands" : [
+        { "kind" : "IdResultType" },
+        { "kind" : "IdResult" },
+        { "kind" : "IdRef",        "name" : "'Operand 1'" },
+        { "kind" : "IdRef",        "name" : "'Operand 2'" }
+      ],
+      "version" : "1.4"
+    },
+    {
+      "opname" : "OpPtrDiff",
+      "opcode" : 403,
+      "operands" : [
+        { "kind" : "IdResultType" },
+        { "kind" : "IdResult" },
+        { "kind" : "IdRef",        "name" : "'Operand 1'" },
+        { "kind" : "IdRef",        "name" : "'Operand 2'" }
+      ],
+      "capabilities" : [ "Addresses", "VariablePointers", "VariablePointersStorageBuffer" ],
+      "version" : "1.4"
+    },
+    {
       "opname" : "OpSubgroupBallotKHR",
       "opcode" : 4421,
       "operands" : [
@@ -4119,6 +4166,16 @@
       "version" : "None"
     },
     {
+      "opname" : "OpDecorateString",
+      "opcode" : 5632,
+      "operands" : [
+        { "kind" : "IdRef",         "name" : "'Target'" },
+        { "kind" : "Decoration" }
+      ],
+      "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ],
+      "version" : "1.4"
+    },
+    {
       "opname" : "OpDecorateStringGOOGLE",
       "opcode" : 5632,
       "operands" : [
@@ -4126,7 +4183,18 @@
         { "kind" : "Decoration" }
       ],
       "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ],
-      "version" : "None"
+      "version" : "1.4"
+    },
+    {
+      "opname" : "OpMemberDecorateString",
+      "opcode" : 5633,
+      "operands" : [
+        { "kind" : "IdRef",          "name" : "'Struct Type'" },
+        { "kind" : "LiteralInteger", "name" : "'Member'" },
+        { "kind" : "Decoration" }
+      ],
+      "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ],
+      "version" : "1.4"
     },
     {
       "opname" : "OpMemberDecorateStringGOOGLE",
@@ -4137,7 +4205,7 @@
         { "kind" : "Decoration" }
       ],
       "extensions" : [ "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1" ],
-      "version" : "None"
+      "version" : "1.4"
     },
     {
       "opname" : "OpVmeImageINTEL",
@@ -5634,6 +5702,16 @@
           "enumerant" : "VolatileTexelKHR",
           "value" : "0x0800",
           "capabilities" : [ "VulkanMemoryModelKHR" ]
+        },
+        {
+          "enumerant" : "SignExtend",
+          "value" : "0x1000",
+          "version" : "1.4"
+        },
+        {
+          "enumerant" : "ZeroExtend",
+          "value" : "0x2000",
+          "version" : "1.4"
         }
       ]
     },
@@ -5718,6 +5796,46 @@
             { "kind" : "LiteralInteger" }
           ],
           "version" : "1.1"
+        },
+        {
+          "enumerant" : "MinIterations",
+          "value" : "0x0010",
+          "parameters" : [
+            { "kind" : "LiteralInteger" }
+          ],
+          "version" : "1.4"
+        },
+        {
+          "enumerant" : "MaxIterations",
+          "value" : "0x0020",
+          "parameters" : [
+            { "kind" : "LiteralInteger" }
+          ],
+          "version" : "1.4"
+        },
+        {
+          "enumerant" : "IterationMultiple",
+          "value" : "0x0040",
+          "parameters" : [
+            { "kind" : "LiteralInteger" }
+          ],
+          "version" : "1.4"
+        },
+        {
+          "enumerant" : "PeelCount",
+          "value" : "0x0080",
+          "parameters" : [
+            { "kind" : "LiteralInteger" }
+          ],
+          "version" : "1.4"
+        },
+        {
+          "enumerant" : "PartialCount",
+          "value" : "0x0100",
+          "parameters" : [
+            { "kind" : "LiteralInteger" }
+          ],
+          "version" : "1.4"
         }
       ]
     },
@@ -6284,7 +6402,7 @@
           "extensions" : [ "SPV_KHR_post_depth_coverage" ],
           "version" : "None"
         },
-{
+        {
           "enumerant" : "DenormPreserve",
           "value" : 4459,
           "capabilities" : [ "DenormPreserve" ],
@@ -6292,7 +6410,7 @@
           "parameters" : [
             { "kind" : "LiteralInteger", "name" : "'Target Width'" }
           ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "DenormFlushToZero",
@@ -6302,7 +6420,7 @@
           "parameters" : [
             { "kind" : "LiteralInteger", "name" : "'Target Width'" }
           ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "SignedZeroInfNanPreserve",
@@ -6312,7 +6430,7 @@
           "parameters" : [
             { "kind" : "LiteralInteger", "name" : "'Target Width'" }
           ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "RoundingModeRTE",
@@ -6322,7 +6440,7 @@
           "parameters" : [
             { "kind" : "LiteralInteger", "name" : "'Target Width'" }
           ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "RoundingModeRTZ",
@@ -6332,7 +6450,7 @@
           "parameters" : [
             { "kind" : "LiteralInteger", "name" : "'Target Width'" }
           ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "StencilRefReplacingEXT",
@@ -7112,7 +7230,8 @@
         {
           "enumerant" : "BufferBlock",
           "value" : 3,
-          "capabilities" : [ "Shader" ]
+          "capabilities" : [ "Shader" ],
+          "lastVersion" : "1.3"
         },
         {
           "enumerant" : "RowMajor",
@@ -7227,6 +7346,15 @@
           "capabilities" : [ "Shader" ]
         },
         {
+          "enumerant" : "UniformId",
+          "value" : 27,
+          "capabilities" : [ "Shader" ],
+          "parameters" : [
+            { "kind" : "IdScope",           "name" : "'Execution'" }
+          ],
+          "version" : "1.4"
+        },
+        {
           "enumerant" : "SaturatedConversion",
           "value" : 28,
           "capabilities" : [ "Kernel" ]
@@ -7387,13 +7515,13 @@
           "enumerant" : "NoSignedWrap",
           "value" : 4469,
           "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "NoUnsignedWrap",
           "value" : 4470,
           "extensions" : [ "SPV_KHR_no_integer_wrap_decoration" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "ExplicitInterpAMD",
@@ -7452,7 +7580,7 @@
           "extensions" : [ "SPV_NV_mesh_shader" ],
           "version" : "None"
         },
-		{
+        {
           "enumerant" : "PerVertexNV",
           "value" : 5285,
           "capabilities" : [ "FragmentBarycentricNV" ],
@@ -7465,6 +7593,14 @@
           "capabilities" : [ "ShaderNonUniformEXT" ]
         },
         {
+          "enumerant" : "CounterBuffer",
+          "value" : 5634,
+          "parameters" : [
+            { "kind" : "IdRef", "name" : "'Counter Buffer'" }
+          ],
+          "version" : "1.4"
+        },
+        {
           "enumerant" : "HlslCounterBufferGOOGLE",
           "value" : 5634,
           "parameters" : [
@@ -7474,6 +7610,14 @@
           "version" : "None"
         },
         {
+          "enumerant" : "UserSemantic",
+          "value" : 5635,
+          "parameters" : [
+            { "kind" : "LiteralString", "name" : "'Semantic'" }
+          ],
+          "version" : "1.4"
+        },
+        {
           "enumerant" : "HlslSemanticGOOGLE",
           "value" : 5635,
           "parameters" : [
@@ -8638,31 +8782,31 @@
           "enumerant" : "DenormPreserve",
           "value" : 4464,
           "extensions" : [ "SPV_KHR_float_controls" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "DenormFlushToZero",
           "value" : 4465,
           "extensions" : [ "SPV_KHR_float_controls" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "SignedZeroInfNanPreserve",
           "value" : 4466,
           "extensions" : [ "SPV_KHR_float_controls" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "RoundingModeRTE",
           "value" : 4467,
           "extensions" : [ "SPV_KHR_float_controls" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "RoundingModeRTZ",
           "value" : 4468,
           "extensions" : [ "SPV_KHR_float_controls" ],
-          "version" : "None"
+          "version" : "1.4"
         },
         {
           "enumerant" : "Float16ImageAMD",
diff --git a/include/spirv/unified1/spirv.cs b/include/spirv/unified1/spirv.cs
index 4b0a4ac..e139cfd 100644
--- a/include/spirv/unified1/spirv.cs
+++ b/include/spirv/unified1/spirv.cs
@@ -48,8 +48,8 @@
     public static class Specification
     {
         public const uint MagicNumber = 0x07230203;
-        public const uint Version = 0x00010300;
-        public const uint Revision = 7;
+        public const uint Version = 0x00010400;
+        public const uint Revision = 1;
         public const uint OpCodeMask = 0xffff;
         public const uint WordCountShift = 16;
 
@@ -305,6 +305,8 @@
             MakeTexelVisibleKHR = 9,
             NonPrivateTexelKHR = 10,
             VolatileTexelKHR = 11,
+            SignExtend = 12,
+            ZeroExtend = 13,
         }
 
         public enum ImageOperandsMask
@@ -322,6 +324,8 @@
             MakeTexelVisibleKHR = 0x00000200,
             NonPrivateTexelKHR = 0x00000400,
             VolatileTexelKHR = 0x00000800,
+            SignExtend = 0x00001000,
+            ZeroExtend = 0x00002000,
         }
 
         public enum FPFastMathModeShift
@@ -404,6 +408,7 @@
             NonWritable = 24,
             NonReadable = 25,
             Uniform = 26,
+            UniformId = 27,
             SaturatedConversion = 28,
             Stream = 29,
             Location = 30,
@@ -438,8 +443,10 @@
             NonUniformEXT = 5300,
             RestrictPointerEXT = 5355,
             AliasedPointerEXT = 5356,
+            CounterBuffer = 5634,
             HlslCounterBufferGOOGLE = 5634,
             HlslSemanticGOOGLE = 5635,
+            UserSemantic = 5635,
         }
 
         public enum BuiltIn
@@ -563,6 +570,11 @@
             DontUnroll = 1,
             DependencyInfinite = 2,
             DependencyLength = 3,
+            MinIterations = 4,
+            MaxIterations = 5,
+            IterationMultiple = 6,
+            PeelCount = 7,
+            PartialCount = 8,
         }
 
         public enum LoopControlMask
@@ -572,6 +584,11 @@
             DontUnroll = 0x00000002,
             DependencyInfinite = 0x00000004,
             DependencyLength = 0x00000008,
+            MinIterations = 0x00000010,
+            MaxIterations = 0x00000020,
+            IterationMultiple = 0x00000040,
+            PeelCount = 0x00000080,
+            PartialCount = 0x00000100,
         }
 
         public enum FunctionControlShift
@@ -1167,6 +1184,10 @@
             OpGroupNonUniformLogicalXor = 364,
             OpGroupNonUniformQuadBroadcast = 365,
             OpGroupNonUniformQuadSwap = 366,
+            OpCopyLogical = 400,
+            OpPtrEqual = 401,
+            OpPtrNotEqual = 402,
+            OpPtrDiff = 403,
             OpSubgroupBallotKHR = 4421,
             OpSubgroupFirstInvocationKHR = 4422,
             OpSubgroupAllKHR = 4428,
@@ -1207,7 +1228,9 @@
             OpSubgroupImageBlockWriteINTEL = 5578,
             OpSubgroupImageMediaBlockReadINTEL = 5580,
             OpSubgroupImageMediaBlockWriteINTEL = 5581,
+            OpDecorateString = 5632,
             OpDecorateStringGOOGLE = 5632,
+            OpMemberDecorateString = 5633,
             OpMemberDecorateStringGOOGLE = 5633,
             OpVmeImageINTEL = 5699,
             OpTypeVmeImageINTEL = 5700,
diff --git a/include/spirv/unified1/spirv.h b/include/spirv/unified1/spirv.h
index 06207d0..9eb4ed7 100644
--- a/include/spirv/unified1/spirv.h
+++ b/include/spirv/unified1/spirv.h
@@ -53,12 +53,12 @@
 
 typedef unsigned int SpvId;
 
-#define SPV_VERSION 0x10300
-#define SPV_REVISION 7
+#define SPV_VERSION 0x10400
+#define SPV_REVISION 1
 
 static const unsigned int SpvMagicNumber = 0x07230203;
-static const unsigned int SpvVersion = 0x00010300;
-static const unsigned int SpvRevision = 7;
+static const unsigned int SpvVersion = 0x00010400;
+static const unsigned int SpvRevision = 1;
 static const unsigned int SpvOpCodeMask = 0xffff;
 static const unsigned int SpvWordCountShift = 16;
 
@@ -313,6 +313,8 @@
     SpvImageOperandsMakeTexelVisibleKHRShift = 9,
     SpvImageOperandsNonPrivateTexelKHRShift = 10,
     SpvImageOperandsVolatileTexelKHRShift = 11,
+    SpvImageOperandsSignExtendShift = 12,
+    SpvImageOperandsZeroExtendShift = 13,
     SpvImageOperandsMax = 0x7fffffff,
 } SpvImageOperandsShift;
 
@@ -330,6 +332,8 @@
     SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
     SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400,
     SpvImageOperandsVolatileTexelKHRMask = 0x00000800,
+    SpvImageOperandsSignExtendMask = 0x00001000,
+    SpvImageOperandsZeroExtendMask = 0x00002000,
 } SpvImageOperandsMask;
 
 typedef enum SpvFPFastMathModeShift_ {
@@ -410,6 +414,7 @@
     SpvDecorationNonWritable = 24,
     SpvDecorationNonReadable = 25,
     SpvDecorationUniform = 26,
+    SpvDecorationUniformId = 27,
     SpvDecorationSaturatedConversion = 28,
     SpvDecorationStream = 29,
     SpvDecorationLocation = 30,
@@ -444,8 +449,10 @@
     SpvDecorationNonUniformEXT = 5300,
     SpvDecorationRestrictPointerEXT = 5355,
     SpvDecorationAliasedPointerEXT = 5356,
+    SpvDecorationCounterBuffer = 5634,
     SpvDecorationHlslCounterBufferGOOGLE = 5634,
     SpvDecorationHlslSemanticGOOGLE = 5635,
+    SpvDecorationUserSemantic = 5635,
     SpvDecorationMax = 0x7fffffff,
 } SpvDecoration;
 
@@ -568,6 +575,11 @@
     SpvLoopControlDontUnrollShift = 1,
     SpvLoopControlDependencyInfiniteShift = 2,
     SpvLoopControlDependencyLengthShift = 3,
+    SpvLoopControlMinIterationsShift = 4,
+    SpvLoopControlMaxIterationsShift = 5,
+    SpvLoopControlIterationMultipleShift = 6,
+    SpvLoopControlPeelCountShift = 7,
+    SpvLoopControlPartialCountShift = 8,
     SpvLoopControlMax = 0x7fffffff,
 } SpvLoopControlShift;
 
@@ -577,6 +589,11 @@
     SpvLoopControlDontUnrollMask = 0x00000002,
     SpvLoopControlDependencyInfiniteMask = 0x00000004,
     SpvLoopControlDependencyLengthMask = 0x00000008,
+    SpvLoopControlMinIterationsMask = 0x00000010,
+    SpvLoopControlMaxIterationsMask = 0x00000020,
+    SpvLoopControlIterationMultipleMask = 0x00000040,
+    SpvLoopControlPeelCountMask = 0x00000080,
+    SpvLoopControlPartialCountMask = 0x00000100,
 } SpvLoopControlMask;
 
 typedef enum SpvFunctionControlShift_ {
@@ -1167,6 +1184,10 @@
     SpvOpGroupNonUniformLogicalXor = 364,
     SpvOpGroupNonUniformQuadBroadcast = 365,
     SpvOpGroupNonUniformQuadSwap = 366,
+    SpvOpCopyLogical = 400,
+    SpvOpPtrEqual = 401,
+    SpvOpPtrNotEqual = 402,
+    SpvOpPtrDiff = 403,
     SpvOpSubgroupBallotKHR = 4421,
     SpvOpSubgroupFirstInvocationKHR = 4422,
     SpvOpSubgroupAllKHR = 4428,
@@ -1207,7 +1228,9 @@
     SpvOpSubgroupImageBlockWriteINTEL = 5578,
     SpvOpSubgroupImageMediaBlockReadINTEL = 5580,
     SpvOpSubgroupImageMediaBlockWriteINTEL = 5581,
+    SpvOpDecorateString = 5632,
     SpvOpDecorateStringGOOGLE = 5632,
+    SpvOpMemberDecorateString = 5633,
     SpvOpMemberDecorateStringGOOGLE = 5633,
     SpvOpVmeImageINTEL = 5699,
     SpvOpTypeVmeImageINTEL = 5700,
@@ -1675,6 +1698,10 @@
     case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
     case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
     case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
+    case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break;
+    case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break;
+    case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
+    case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break;
     case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
     case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
     case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
@@ -1715,7 +1742,9 @@
     case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+    case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break;
     case SpvOpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
+    case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
     case SpvOpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/include/spirv/unified1/spirv.hpp b/include/spirv/unified1/spirv.hpp
index 6bd95b0..5297fd3 100644
--- a/include/spirv/unified1/spirv.hpp
+++ b/include/spirv/unified1/spirv.hpp
@@ -49,12 +49,12 @@
 
 typedef unsigned int Id;
 
-#define SPV_VERSION 0x10300
-#define SPV_REVISION 7
+#define SPV_VERSION 0x10400
+#define SPV_REVISION 1
 
 static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 0x00010300;
-static const unsigned int Revision = 7;
+static const unsigned int Version = 0x00010400;
+static const unsigned int Revision = 1;
 static const unsigned int OpCodeMask = 0xffff;
 static const unsigned int WordCountShift = 16;
 
@@ -309,6 +309,8 @@
     ImageOperandsMakeTexelVisibleKHRShift = 9,
     ImageOperandsNonPrivateTexelKHRShift = 10,
     ImageOperandsVolatileTexelKHRShift = 11,
+    ImageOperandsSignExtendShift = 12,
+    ImageOperandsZeroExtendShift = 13,
     ImageOperandsMax = 0x7fffffff,
 };
 
@@ -326,6 +328,8 @@
     ImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
     ImageOperandsNonPrivateTexelKHRMask = 0x00000400,
     ImageOperandsVolatileTexelKHRMask = 0x00000800,
+    ImageOperandsSignExtendMask = 0x00001000,
+    ImageOperandsZeroExtendMask = 0x00002000,
 };
 
 enum FPFastMathModeShift {
@@ -406,6 +410,7 @@
     DecorationNonWritable = 24,
     DecorationNonReadable = 25,
     DecorationUniform = 26,
+    DecorationUniformId = 27,
     DecorationSaturatedConversion = 28,
     DecorationStream = 29,
     DecorationLocation = 30,
@@ -440,8 +445,10 @@
     DecorationNonUniformEXT = 5300,
     DecorationRestrictPointerEXT = 5355,
     DecorationAliasedPointerEXT = 5356,
+    DecorationCounterBuffer = 5634,
     DecorationHlslCounterBufferGOOGLE = 5634,
     DecorationHlslSemanticGOOGLE = 5635,
+    DecorationUserSemantic = 5635,
     DecorationMax = 0x7fffffff,
 };
 
@@ -564,6 +571,11 @@
     LoopControlDontUnrollShift = 1,
     LoopControlDependencyInfiniteShift = 2,
     LoopControlDependencyLengthShift = 3,
+    LoopControlMinIterationsShift = 4,
+    LoopControlMaxIterationsShift = 5,
+    LoopControlIterationMultipleShift = 6,
+    LoopControlPeelCountShift = 7,
+    LoopControlPartialCountShift = 8,
     LoopControlMax = 0x7fffffff,
 };
 
@@ -573,6 +585,11 @@
     LoopControlDontUnrollMask = 0x00000002,
     LoopControlDependencyInfiniteMask = 0x00000004,
     LoopControlDependencyLengthMask = 0x00000008,
+    LoopControlMinIterationsMask = 0x00000010,
+    LoopControlMaxIterationsMask = 0x00000020,
+    LoopControlIterationMultipleMask = 0x00000040,
+    LoopControlPeelCountMask = 0x00000080,
+    LoopControlPartialCountMask = 0x00000100,
 };
 
 enum FunctionControlShift {
@@ -1163,6 +1180,10 @@
     OpGroupNonUniformLogicalXor = 364,
     OpGroupNonUniformQuadBroadcast = 365,
     OpGroupNonUniformQuadSwap = 366,
+    OpCopyLogical = 400,
+    OpPtrEqual = 401,
+    OpPtrNotEqual = 402,
+    OpPtrDiff = 403,
     OpSubgroupBallotKHR = 4421,
     OpSubgroupFirstInvocationKHR = 4422,
     OpSubgroupAllKHR = 4428,
@@ -1203,7 +1224,9 @@
     OpSubgroupImageBlockWriteINTEL = 5578,
     OpSubgroupImageMediaBlockReadINTEL = 5580,
     OpSubgroupImageMediaBlockWriteINTEL = 5581,
+    OpDecorateString = 5632,
     OpDecorateStringGOOGLE = 5632,
+    OpMemberDecorateString = 5633,
     OpMemberDecorateStringGOOGLE = 5633,
     OpVmeImageINTEL = 5699,
     OpTypeVmeImageINTEL = 5700,
@@ -1671,6 +1694,10 @@
     case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
     case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
     case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
+    case OpCopyLogical: *hasResult = true; *hasResultType = true; break;
+    case OpPtrEqual: *hasResult = true; *hasResultType = true; break;
+    case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
+    case OpPtrDiff: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
@@ -1711,7 +1738,9 @@
     case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+    case OpDecorateString: *hasResult = false; *hasResultType = false; break;
     case OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
+    case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
     case OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/include/spirv/unified1/spirv.hpp11 b/include/spirv/unified1/spirv.hpp11
index bebcce2..3427b37 100644
--- a/include/spirv/unified1/spirv.hpp11
+++ b/include/spirv/unified1/spirv.hpp11
@@ -49,12 +49,12 @@
 
 typedef unsigned int Id;
 
-#define SPV_VERSION 0x10300
-#define SPV_REVISION 7
+#define SPV_VERSION 0x10400
+#define SPV_REVISION 1
 
 static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 0x00010300;
-static const unsigned int Revision = 7;
+static const unsigned int Version = 0x00010400;
+static const unsigned int Revision = 1;
 static const unsigned int OpCodeMask = 0xffff;
 static const unsigned int WordCountShift = 16;
 
@@ -309,6 +309,8 @@
     MakeTexelVisibleKHR = 9,
     NonPrivateTexelKHR = 10,
     VolatileTexelKHR = 11,
+    SignExtend = 12,
+    ZeroExtend = 13,
     Max = 0x7fffffff,
 };
 
@@ -326,6 +328,8 @@
     MakeTexelVisibleKHR = 0x00000200,
     NonPrivateTexelKHR = 0x00000400,
     VolatileTexelKHR = 0x00000800,
+    SignExtend = 0x00001000,
+    ZeroExtend = 0x00002000,
 };
 
 enum class FPFastMathModeShift : unsigned {
@@ -406,6 +410,7 @@
     NonWritable = 24,
     NonReadable = 25,
     Uniform = 26,
+    UniformId = 27,
     SaturatedConversion = 28,
     Stream = 29,
     Location = 30,
@@ -440,8 +445,10 @@
     NonUniformEXT = 5300,
     RestrictPointerEXT = 5355,
     AliasedPointerEXT = 5356,
+    CounterBuffer = 5634,
     HlslCounterBufferGOOGLE = 5634,
     HlslSemanticGOOGLE = 5635,
+    UserSemantic = 5635,
     Max = 0x7fffffff,
 };
 
@@ -564,6 +571,11 @@
     DontUnroll = 1,
     DependencyInfinite = 2,
     DependencyLength = 3,
+    MinIterations = 4,
+    MaxIterations = 5,
+    IterationMultiple = 6,
+    PeelCount = 7,
+    PartialCount = 8,
     Max = 0x7fffffff,
 };
 
@@ -573,6 +585,11 @@
     DontUnroll = 0x00000002,
     DependencyInfinite = 0x00000004,
     DependencyLength = 0x00000008,
+    MinIterations = 0x00000010,
+    MaxIterations = 0x00000020,
+    IterationMultiple = 0x00000040,
+    PeelCount = 0x00000080,
+    PartialCount = 0x00000100,
 };
 
 enum class FunctionControlShift : unsigned {
@@ -1163,6 +1180,10 @@
     OpGroupNonUniformLogicalXor = 364,
     OpGroupNonUniformQuadBroadcast = 365,
     OpGroupNonUniformQuadSwap = 366,
+    OpCopyLogical = 400,
+    OpPtrEqual = 401,
+    OpPtrNotEqual = 402,
+    OpPtrDiff = 403,
     OpSubgroupBallotKHR = 4421,
     OpSubgroupFirstInvocationKHR = 4422,
     OpSubgroupAllKHR = 4428,
@@ -1203,7 +1224,9 @@
     OpSubgroupImageBlockWriteINTEL = 5578,
     OpSubgroupImageMediaBlockReadINTEL = 5580,
     OpSubgroupImageMediaBlockWriteINTEL = 5581,
+    OpDecorateString = 5632,
     OpDecorateStringGOOGLE = 5632,
+    OpMemberDecorateString = 5633,
     OpMemberDecorateStringGOOGLE = 5633,
     OpVmeImageINTEL = 5699,
     OpTypeVmeImageINTEL = 5700,
@@ -1671,6 +1694,10 @@
     case Op::OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
     case Op::OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
     case Op::OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
+    case Op::OpCopyLogical: *hasResult = true; *hasResultType = true; break;
+    case Op::OpPtrEqual: *hasResult = true; *hasResultType = true; break;
+    case Op::OpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
+    case Op::OpPtrDiff: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
@@ -1711,7 +1738,9 @@
     case Op::OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
     case Op::OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+    case Op::OpDecorateString: *hasResult = false; *hasResultType = false; break;
     case Op::OpDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
+    case Op::OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
     case Op::OpMemberDecorateStringGOOGLE: *hasResult = false; *hasResultType = false; break;
     case Op::OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
     case Op::OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
diff --git a/include/spirv/unified1/spirv.json b/include/spirv/unified1/spirv.json
index 876449e..9dbbd83 100644
--- a/include/spirv/unified1/spirv.json
+++ b/include/spirv/unified1/spirv.json
@@ -54,8 +54,8 @@
                 ]
             ],
             "MagicNumber": 119734787,
-            "Version": 66304,
-            "Revision": 7,
+            "Version": 66560,
+            "Revision": 1,
             "OpCodeMask": 65535,
             "WordCountShift": 16
         },
@@ -351,7 +351,9 @@
                     "MakeTexelAvailableKHR": 8,
                     "MakeTexelVisibleKHR": 9,
                     "NonPrivateTexelKHR": 10,
-                    "VolatileTexelKHR": 11
+                    "VolatileTexelKHR": 11,
+                    "SignExtend": 12,
+                    "ZeroExtend": 13
                 }
             },
             {
@@ -442,6 +444,7 @@
                     "NonWritable": 24,
                     "NonReadable": 25,
                     "Uniform": 26,
+                    "UniformId": 27,
                     "SaturatedConversion": 28,
                     "Stream": 29,
                     "Location": 30,
@@ -476,8 +479,10 @@
                     "NonUniformEXT": 5300,
                     "RestrictPointerEXT": 5355,
                     "AliasedPointerEXT": 5356,
+                    "CounterBuffer": 5634,
                     "HlslCounterBufferGOOGLE": 5634,
                     "HlslSemanticGOOGLE": 5635
+                    "UserSemantic": 5635
                 }
             },
             {
@@ -602,7 +607,12 @@
                     "Unroll": 0,
                     "DontUnroll": 1,
                     "DependencyInfinite": 2,
-                    "DependencyLength": 3
+                    "DependencyLength": 3,
+                    "MinIterations": 4,
+                    "MaxIterations": 5,
+                    "IterationMultiple": 6,
+                    "PeelCount": 7,
+                    "PartialCount": 8
                 }
             },
             {
@@ -1181,6 +1191,10 @@
                     "OpGroupNonUniformLogicalXor": 364,
                     "OpGroupNonUniformQuadBroadcast": 365,
                     "OpGroupNonUniformQuadSwap": 366,
+                    "OpCopyLogical": 400,
+                    "OpPtrEqual": 401,
+                    "OpPtrNotEqual": 402,
+                    "OpPtrDiff": 403,
                     "OpSubgroupBallotKHR": 4421,
                     "OpSubgroupFirstInvocationKHR": 4422,
                     "OpSubgroupAllKHR": 4428,
@@ -1221,7 +1235,9 @@
                     "OpSubgroupImageBlockWriteINTEL": 5578,
                     "OpSubgroupImageMediaBlockReadINTEL": 5580,
                     "OpSubgroupImageMediaBlockWriteINTEL": 5581,
+                    "OpDecorateString": 5632,
                     "OpDecorateStringGOOGLE": 5632,
+                    "OpMemberDecorateString": 5633,
                     "OpMemberDecorateStringGOOGLE": 5633,
                     "OpVmeImageINTEL": 5699,
                     "OpTypeVmeImageINTEL": 5700,
diff --git a/include/spirv/unified1/spirv.lua b/include/spirv/unified1/spirv.lua
index 820393c..3a4ec13 100644
--- a/include/spirv/unified1/spirv.lua
+++ b/include/spirv/unified1/spirv.lua
@@ -44,8 +44,8 @@
 
 spv = {
     MagicNumber = 0x07230203,
-    Version = 0x00010300,
-    Revision = 7,
+    Version = 0x00010400,
+    Revision = 1,
     OpCodeMask = 0xffff,
     WordCountShift = 16,
 
@@ -288,6 +288,8 @@
         MakeTexelVisibleKHR = 9,
         NonPrivateTexelKHR = 10,
         VolatileTexelKHR = 11,
+        SignExtend = 12,
+        ZeroExtend = 13,
     },
 
     ImageOperandsMask = {
@@ -304,6 +306,8 @@
         MakeTexelVisibleKHR = 0x00000200,
         NonPrivateTexelKHR = 0x00000400,
         VolatileTexelKHR = 0x00000800,
+        SignExtend = 0x00001000,
+        ZeroExtend = 0x00002000,
     },
 
     FPFastMathModeShift = {
@@ -379,6 +383,7 @@
         NonWritable = 24,
         NonReadable = 25,
         Uniform = 26,
+        UniformId = 27,
         SaturatedConversion = 28,
         Stream = 29,
         Location = 30,
@@ -413,8 +418,10 @@
         NonUniformEXT = 5300,
         RestrictPointerEXT = 5355,
         AliasedPointerEXT = 5356,
+        CounterBuffer = 5634,
         HlslCounterBufferGOOGLE = 5634,
         HlslSemanticGOOGLE = 5635,
+        UserSemantic = 5635,
     },
 
     BuiltIn = {
@@ -534,6 +541,11 @@
         DontUnroll = 1,
         DependencyInfinite = 2,
         DependencyLength = 3,
+        MinIterations = 4,
+        MaxIterations = 5,
+        IterationMultiple = 6,
+        PeelCount = 7,
+        PartialCount = 8,
     },
 
     LoopControlMask = {
@@ -542,6 +554,11 @@
         DontUnroll = 0x00000002,
         DependencyInfinite = 0x00000004,
         DependencyLength = 0x00000008,
+        MinIterations = 0x00000010,
+        MaxIterations = 0x00000020,
+        IterationMultiple = 0x00000040,
+        PeelCount = 0x00000080,
+        PartialCount = 0x00000100,
     },
 
     FunctionControlShift = {
@@ -1124,6 +1141,10 @@
         OpGroupNonUniformLogicalXor = 364,
         OpGroupNonUniformQuadBroadcast = 365,
         OpGroupNonUniformQuadSwap = 366,
+        OpCopyLogical = 400,
+        OpPtrEqual = 401,
+        OpPtrNotEqual = 402,
+        OpPtrDiff = 403,
         OpSubgroupBallotKHR = 4421,
         OpSubgroupFirstInvocationKHR = 4422,
         OpSubgroupAllKHR = 4428,
@@ -1164,7 +1185,9 @@
         OpSubgroupImageBlockWriteINTEL = 5578,
         OpSubgroupImageMediaBlockReadINTEL = 5580,
         OpSubgroupImageMediaBlockWriteINTEL = 5581,
+        OpDecorateString = 5632,
         OpDecorateStringGOOGLE = 5632,
+        OpMemberDecorateString = 5633,
         OpMemberDecorateStringGOOGLE = 5633,
         OpVmeImageINTEL = 5699,
         OpTypeVmeImageINTEL = 5700,
diff --git a/include/spirv/unified1/spirv.py b/include/spirv/unified1/spirv.py
index e44040b..4df3ba9 100644
--- a/include/spirv/unified1/spirv.py
+++ b/include/spirv/unified1/spirv.py
@@ -44,8 +44,8 @@
 
 spv = {
     'MagicNumber' : 0x07230203,
-    'Version' : 0x00010300,
-    'Revision' : 7,
+    'Version' : 0x00010400,
+    'Revision' : 1,
     'OpCodeMask' : 0xffff,
     'WordCountShift' : 16,
 
@@ -288,6 +288,8 @@
         'MakeTexelVisibleKHR' : 9,
         'NonPrivateTexelKHR' : 10,
         'VolatileTexelKHR' : 11,
+        'SignExtend' : 12,
+        'ZeroExtend' : 13,
     },
 
     'ImageOperandsMask' : {
@@ -304,6 +306,8 @@
         'MakeTexelVisibleKHR' : 0x00000200,
         'NonPrivateTexelKHR' : 0x00000400,
         'VolatileTexelKHR' : 0x00000800,
+        'SignExtend' : 0x00001000,
+        'ZeroExtend' : 0x00002000,
     },
 
     'FPFastMathModeShift' : {
@@ -379,6 +383,7 @@
         'NonWritable' : 24,
         'NonReadable' : 25,
         'Uniform' : 26,
+        'UniformId' : 27,
         'SaturatedConversion' : 28,
         'Stream' : 29,
         'Location' : 30,
@@ -413,8 +418,10 @@
         'NonUniformEXT' : 5300,
         'RestrictPointerEXT' : 5355,
         'AliasedPointerEXT' : 5356,
+        'CounterBuffer' : 5634,
         'HlslCounterBufferGOOGLE' : 5634,
         'HlslSemanticGOOGLE' : 5635,
+        'UserSemantic' : 5635,
     },
 
     'BuiltIn' : {
@@ -534,6 +541,11 @@
         'DontUnroll' : 1,
         'DependencyInfinite' : 2,
         'DependencyLength' : 3,
+        'MinIterations' : 4,
+        'MaxIterations' : 5,
+        'IterationMultiple' : 6,
+        'PeelCount' : 7,
+        'PartialCount' : 8,
     },
 
     'LoopControlMask' : {
@@ -542,6 +554,11 @@
         'DontUnroll' : 0x00000002,
         'DependencyInfinite' : 0x00000004,
         'DependencyLength' : 0x00000008,
+        'MinIterations' : 0x00000010,
+        'MaxIterations' : 0x00000020,
+        'IterationMultiple' : 0x00000040,
+        'PeelCount' : 0x00000080,
+        'PartialCount' : 0x00000100,
     },
 
     'FunctionControlShift' : {
@@ -1124,6 +1141,10 @@
         'OpGroupNonUniformLogicalXor' : 364,
         'OpGroupNonUniformQuadBroadcast' : 365,
         'OpGroupNonUniformQuadSwap' : 366,
+        'OpCopyLogical' : 400,
+        'OpPtrEqual' : 401,
+        'OpPtrNotEqual' : 402,
+        'OpPtrDiff' : 403,
         'OpSubgroupBallotKHR' : 4421,
         'OpSubgroupFirstInvocationKHR' : 4422,
         'OpSubgroupAllKHR' : 4428,
@@ -1164,7 +1185,9 @@
         'OpSubgroupImageBlockWriteINTEL' : 5578,
         'OpSubgroupImageMediaBlockReadINTEL' : 5580,
         'OpSubgroupImageMediaBlockWriteINTEL' : 5581,
+        'OpDecorateString' : 5632,
         'OpDecorateStringGOOGLE' : 5632,
+        'OpMemberDecorateString' : 5633,
         'OpMemberDecorateStringGOOGLE' : 5633,
         'OpVmeImageINTEL' : 5699,
         'OpTypeVmeImageINTEL' : 5700,
diff --git a/include/spirv/unified1/spv.d b/include/spirv/unified1/spv.d
index 0b6faff..41f6feb 100644
--- a/include/spirv/unified1/spv.d
+++ b/include/spirv/unified1/spv.d
@@ -51,8 +51,8 @@
 module spv;
 
 enum uint MagicNumber = 0x07230203;
-enum uint Version = 0x00010300;
-enum uint Revision = 7;
+enum uint Version = 0x00010400;
+enum uint Revision = 1;
 enum uint OpCodeMask = 0xffff;
 enum uint WordCountShift = 16;
 
@@ -308,6 +308,8 @@
     MakeTexelVisibleKHR = 9,
     NonPrivateTexelKHR = 10,
     VolatileTexelKHR = 11,
+    SignExtend = 12,
+    ZeroExtend = 13,
 }
 
 enum ImageOperandsMask : uint
@@ -325,6 +327,8 @@
     MakeTexelVisibleKHR = 0x00000200,
     NonPrivateTexelKHR = 0x00000400,
     VolatileTexelKHR = 0x00000800,
+    SignExtend = 0x00001000,
+    ZeroExtend = 0x00002000,
 }
 
 enum FPFastMathModeShift : uint
@@ -407,6 +411,7 @@
     NonWritable = 24,
     NonReadable = 25,
     Uniform = 26,
+    UniformId = 27,
     SaturatedConversion = 28,
     Stream = 29,
     Location = 30,
@@ -441,8 +446,10 @@
     NonUniformEXT = 5300,
     RestrictPointerEXT = 5355,
     AliasedPointerEXT = 5356,
+    CounterBuffer = 5634,
     HlslCounterBufferGOOGLE = 5634,
     HlslSemanticGOOGLE = 5635,
+    UserSemantic = 5635,
 }
 
 enum BuiltIn : uint
@@ -566,6 +573,11 @@
     DontUnroll = 1,
     DependencyInfinite = 2,
     DependencyLength = 3,
+    MinIterations = 4,
+    MaxIterations = 5,
+    IterationMultiple = 6,
+    PeelCount = 7,
+    PartialCount = 8,
 }
 
 enum LoopControlMask : uint
@@ -575,6 +587,11 @@
     DontUnroll = 0x00000002,
     DependencyInfinite = 0x00000004,
     DependencyLength = 0x00000008,
+    MinIterations = 0x00000010,
+    MaxIterations = 0x00000020,
+    IterationMultiple = 0x00000040,
+    PeelCount = 0x00000080,
+    PartialCount = 0x00000100,
 }
 
 enum FunctionControlShift : uint
@@ -1170,6 +1187,10 @@
     OpGroupNonUniformLogicalXor = 364,
     OpGroupNonUniformQuadBroadcast = 365,
     OpGroupNonUniformQuadSwap = 366,
+    OpCopyLogical = 400,
+    OpPtrEqual = 401,
+    OpPtrNotEqual = 402,
+    OpPtrDiff = 403,
     OpSubgroupBallotKHR = 4421,
     OpSubgroupFirstInvocationKHR = 4422,
     OpSubgroupAllKHR = 4428,
@@ -1210,7 +1231,9 @@
     OpSubgroupImageBlockWriteINTEL = 5578,
     OpSubgroupImageMediaBlockReadINTEL = 5580,
     OpSubgroupImageMediaBlockWriteINTEL = 5581,
+    OpDecorateString = 5632,
     OpDecorateStringGOOGLE = 5632,
+    OpMemberDecorateString = 5633,
     OpMemberDecorateStringGOOGLE = 5633,
     OpVmeImageINTEL = 5699,
     OpTypeVmeImageINTEL = 5700,
diff --git a/tools/buildHeaders/header.cpp b/tools/buildHeaders/header.cpp
index 83553fc..68a2929 100644
--- a/tools/buildHeaders/header.cpp
+++ b/tools/buildHeaders/header.cpp
@@ -68,9 +68,9 @@
         TPrinter();
 
         static const int         DocMagicNumber = 0x07230203;
-        static const int         DocVersion     = 0x00010300;
-        static const int         DocRevision    = 7;
-        #define DocRevisionString                "7"
+        static const int         DocVersion     = 0x00010400;
+        static const int         DocRevision    = 1;
+        #define DocRevisionString                "1"
         static const std::string DocCopyright;
         static const std::string DocComment1;
         static const std::string DocComment2;
diff --git a/tools/buildHeaders/jsonToSpirv.cpp b/tools/buildHeaders/jsonToSpirv.cpp
index e137241..e6cab48 100644
--- a/tools/buildHeaders/jsonToSpirv.cpp
+++ b/tools/buildHeaders/jsonToSpirv.cpp
@@ -119,8 +119,7 @@
         else if (quantifier == "?")
             return {OperandLiteralString, true};
         else {
-            assert(0 && "this case should not exist");
-            return {OperandNone, false};
+            return {OperandOptionalLiteralStrings, false};
         }
     } else if (operandKind == "PairLiteralIntegerIdRef") {
         // Used by OpSwitch in the grammar
@@ -198,7 +197,7 @@
         } else if (operandKind == "FunctionControl") {
             type = OperandFunction;
         } else if (operandKind == "MemoryAccess") {
-            type = OperandMemoryAccess;
+            type = OperandMemoryOperands;
         }
 
         if (type == OperandNone) {
@@ -307,6 +306,7 @@
         const std::string name = inst["opname"].asString();
         EnumCaps caps = getCaps(inst);
         std::string version = inst["version"].asString();
+        std::string lastVersion = inst["lastVersion"].asString();
         Extensions exts = getExts(inst);
         OperandParameters operands;
         bool defResultId = false;
@@ -322,7 +322,7 @@
         }
         InstructionDesc.emplace_back(
             std::move(EnumValue(opcode, name,
-                                std::move(caps), std::move(version), std::move(exts),
+                                std::move(caps), std::move(version), std::move(lastVersion), std::move(exts),
                                 std::move(operands))),
             defTypeId, defResultId);
     }
@@ -355,6 +355,7 @@
                 continue;
             EnumCaps caps(getCaps(enumerant));
             std::string version = enumerant["version"].asString();
+            std::string lastVersion = enumerant["lastVersion"].asString();
             Extensions exts(getExts(enumerant));
             OperandParameters params;
             const Json::Value& paramsJson = enumerant["parameters"];
@@ -369,7 +370,7 @@
             }
             dest->emplace_back(
                 value, enumerant["enumerant"].asString(),
-                std::move(caps), std::move(version), std::move(exts), std::move(params));
+                std::move(caps), std::move(version), std::move(lastVersion), std::move(exts), std::move(params));
         }
     };
 
@@ -437,7 +438,7 @@
         } else if (enumName == "Dim") {
             establishOperandClass(enumName, OperandDimensionality, &DimensionalityParams, operandEnum, category);
         } else if (enumName == "MemoryAccess") {
-            establishOperandClass(enumName, OperandMemoryAccess, &MemoryAccessParams, operandEnum, category);
+            establishOperandClass(enumName, OperandMemoryOperands, &MemoryAccessParams, operandEnum, category);
         } else if (enumName == "Scope") {
             establishOperandClass(enumName, OperandScope, &ScopeParams, operandEnum, category);
         } else if (enumName == "GroupOperation") {
diff --git a/tools/buildHeaders/jsonToSpirv.h b/tools/buildHeaders/jsonToSpirv.h
index 68a141d..beec01c 100644
--- a/tools/buildHeaders/jsonToSpirv.h
+++ b/tools/buildHeaders/jsonToSpirv.h
@@ -47,6 +47,7 @@
     OperandVariableIds,
     OperandOptionalLiteral,
     OperandOptionalLiteralString,
+    OperandOptionalLiteralStrings,
     OperandVariableLiterals,
     OperandVariableIdLiteral,
     OperandVariableLiteralId,
@@ -76,7 +77,7 @@
     OperandLoop,
     OperandFunction,
     OperandMemorySemantics,
-    OperandMemoryAccess,
+    OperandMemoryOperands,
     OperandScope,
 	OperandGroupOperation,
     OperandKernelEnqueueFlags,
@@ -145,6 +146,12 @@
         assert((where != end()) && "Could not find enum in the enum list");
         return *where;
     }
+    // gets *all* entries for the value, including the first one
+    void gatherAliases(unsigned value, std::vector<EValue*>& aliases) {
+        std::for_each(begin(), end(), [&](EValue& e) {
+            if (value == e.value)
+                aliases.push_back(&e);});
+    }
     // Returns the EValue with the given name.  We assume uniqueness
     // by name.
     EValue& at(std::string name) {
@@ -167,9 +174,11 @@
 class EnumValue {
 public:
     EnumValue() : value(0), desc(nullptr) {}
-    EnumValue(unsigned int the_value, const std::string& the_name, EnumCaps&& the_caps, const std::string& the_version,
-              Extensions&& the_extensions, OperandParameters&& the_operands) :
-      value(the_value), name(the_name), capabilities(std::move(the_caps)), version(std::move(the_version)),
+    EnumValue(unsigned int the_value, const std::string& the_name, EnumCaps&& the_caps,
+        const std::string& the_firstVersion, const std::string& the_lastVersion,
+        Extensions&& the_extensions, OperandParameters&& the_operands) :
+      value(the_value), name(the_name), capabilities(std::move(the_caps)),
+      firstVersion(std::move(the_firstVersion)), lastVersion(std::move(the_lastVersion)),
       extensions(std::move(the_extensions)), operands(std::move(the_operands)), desc(nullptr) { }
 
     // For ValueEnum, the value from the JSON file.
@@ -178,7 +187,8 @@
     unsigned value;
     std::string name;
     EnumCaps capabilities;
-    std::string version;
+    std::string firstVersion;
+    std::string lastVersion;
     // A feature only be enabled by certain extensions.
     // An empty list means the feature does not require an extension.
     // Normally, only Capability enums are enabled by extension.  In turn,
@@ -233,10 +243,19 @@
        opDesc("TBD"),
        opClass(0),
        typePresent(has_type),
-       resultPresent(has_result) {}
+       resultPresent(has_result),
+       alias(this) { }
+    InstructionValue(const InstructionValue& v)
+    {
+        *this = v;
+        alias = this;
+    }
 
     bool hasResult() const { return resultPresent != 0; }
     bool hasType()   const { return typePresent != 0; }
+    void setAlias(const InstructionValue& a) { alias = &a; }
+    const InstructionValue& getAlias() const { return *alias; }
+    bool isAlias() const { return alias != this; }
 
     const char* opDesc;
     int opClass;
@@ -244,6 +263,7 @@
 protected:
     int typePresent   : 1;
     int resultPresent : 1;
+    const InstructionValue* alias;    // correct only after discovering the aliases; otherwise points to this
 };
 
 using InstructionValues = EnumValuesContainer<InstructionValue>;