Implement GL_EXT_terminate_invocation (#2454)

* Implement GL_EXT_terminate_invocation.

* terminateInvocation: declare the SPV extension

* Update test results for spirv-tools and bison version bumps

Co-authored-by: John Kessenich <cepheus@frii.com>
diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h
index 2be968e..9610c6e 100644
--- a/SPIRV/GLSL.ext.KHR.h
+++ b/SPIRV/GLSL.ext.KHR.h
@@ -49,4 +49,6 @@
 static const char* const E_SPV_KHR_ray_tracing                  = "SPV_KHR_ray_tracing";
 static const char* const E_SPV_KHR_ray_query                    = "SPV_KHR_ray_query";
 static const char* const E_SPV_KHR_fragment_shading_rate        = "SPV_KHR_fragment_shading_rate";
+static const char* const E_SPV_KHR_terminate_invocation         = "SPV_KHR_terminate_invocation";
+
 #endif  // #ifndef GLSLextKHR_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index ddc6378..e9c14df 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -3458,6 +3458,10 @@
     case glslang::EOpKill:
         builder.makeDiscard();
         break;
+    case glslang::EOpTerminateInvocation:
+        builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
+        builder.makeTerminateInvocation();
+        break;
     case glslang::EOpBreak:
         if (breakForLoop.top())
             builder.createLoopExit();
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 42896ce..85ffe90 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1454,6 +1454,13 @@
 }
 
 // Comments in header
+void Builder::makeTerminateInvocation()
+{
+    buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpTerminateInvocation)));
+    createAndSetNoPredecessorBlock("post-terminate-invocation");
+}
+
+// Comments in header
 Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer)
 {
     Id pointerType = makePointer(storageClass, type);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index f93e182..873c0cd 100644
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -357,8 +357,9 @@
     // Generate all the code needed to finish up a function.
     void leaveFunction();
 
-    // Create a discard.
+    // Create a discard or terminate-invocation.
     void makeDiscard();
+    void makeTerminateInvocation();
 
     // Create a global or function local or IO variable.
     Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 09e035a..3d08204 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -1336,6 +1336,8 @@
     case 365: return "OpGroupNonUniformQuadBroadcast";
     case 366: return "OpGroupNonUniformQuadSwap";
 
+    case OpTerminateInvocation: return "OpTerminateInvocation";
+
     case 4421: return "OpSubgroupBallotKHR";
     case 4422: return "OpSubgroupFirstInvocationKHR";
     case 4428: return "OpSubgroupAllKHR";
@@ -1504,6 +1506,7 @@
     InstructionDesc[OpBranchConditional].setResultAndType(false, false);
     InstructionDesc[OpSwitch].setResultAndType(false, false);
     InstructionDesc[OpKill].setResultAndType(false, false);
+    InstructionDesc[OpTerminateInvocation].setResultAndType(false, false);
     InstructionDesc[OpReturn].setResultAndType(false, false);
     InstructionDesc[OpReturnValue].setResultAndType(false, false);
     InstructionDesc[OpUnreachable].setResultAndType(false, false);
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 26b35bb..ef5670e 100644
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -1849,6 +1849,7 @@
     case OpBranchConditional: *hasResult = false; *hasResultType = false; break;
     case OpSwitch: *hasResult = false; *hasResultType = false; break;
     case OpKill: *hasResult = false; *hasResultType = false; break;
+    case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break;
     case OpReturn: *hasResult = false; *hasResultType = false; break;
     case OpReturnValue: *hasResult = false; *hasResultType = false; break;
     case OpUnreachable: *hasResult = false; *hasResultType = false; break;
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 868b9bf..486e80d 100644
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -263,6 +263,7 @@
         case OpBranchConditional:
         case OpSwitch:
         case OpKill:
+        case OpTerminateInvocation:
         case OpReturn:
         case OpReturnValue:
         case OpUnreachable: