Recognize OpTypeAccelerationStructureNV as a type instruction (#2190)

diff --git a/source/opt/reflect.h b/source/opt/reflect.h
index fb2de7b..79d90bd 100644
--- a/source/opt/reflect.h
+++ b/source/opt/reflect.h
@@ -44,7 +44,8 @@
 }
 inline bool IsTypeInst(SpvOp opcode) {
   return (opcode >= SpvOpTypeVoid && opcode <= SpvOpTypeForwardPointer) ||
-         opcode == SpvOpTypePipeStorage || opcode == SpvOpTypeNamedBarrier;
+         opcode == SpvOpTypePipeStorage || opcode == SpvOpTypeNamedBarrier ||
+         opcode == SpvOpTypeAccelerationStructureNV;
 }
 inline bool IsConstantInst(SpvOp opcode) {
   return opcode >= SpvOpConstantTrue && opcode <= SpvOpSpecConstantOp;
diff --git a/source/opt/type_manager.cpp b/source/opt/type_manager.cpp
index 19eb47e..722b9b9 100644
--- a/source/opt/type_manager.cpp
+++ b/source/opt/type_manager.cpp
@@ -223,6 +223,7 @@
     DefineParameterlessCase(Queue);
     DefineParameterlessCase(PipeStorage);
     DefineParameterlessCase(NamedBarrier);
+    DefineParameterlessCase(AccelerationStructureNV);
 #undef DefineParameterlessCase
     case Type::kInteger:
       typeInst = MakeUnique<Instruction>(
@@ -469,6 +470,7 @@
     DefineNoSubtypeCase(Pipe);
     DefineNoSubtypeCase(PipeStorage);
     DefineNoSubtypeCase(NamedBarrier);
+    DefineNoSubtypeCase(AccelerationStructureNV);
 #undef DefineNoSubtypeCase
     case Type::kVector: {
       const Vector* vec_ty = type.AsVector();
diff --git a/source/opt/types.cpp b/source/opt/types.cpp
index 96644c5..cfafc7d 100644
--- a/source/opt/types.cpp
+++ b/source/opt/types.cpp
@@ -123,6 +123,7 @@
     DeclareKindCase(ForwardPointer);
     DeclareKindCase(PipeStorage);
     DeclareKindCase(NamedBarrier);
+    DeclareKindCase(AccelerationStructureNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
@@ -166,6 +167,7 @@
     DeclareKindCase(ForwardPointer);
     DeclareKindCase(PipeStorage);
     DeclareKindCase(NamedBarrier);
+    DeclareKindCase(AccelerationStructureNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
@@ -214,6 +216,7 @@
     DeclareKindCase(ForwardPointer);
     DeclareKindCase(PipeStorage);
     DeclareKindCase(NamedBarrier);
+    DeclareKindCase(AccelerationStructureNV);
 #undef DeclareKindCase
     default:
       assert(false && "Unhandled type");
diff --git a/source/opt/types.h b/source/opt/types.h
index 28731c6..d77117d 100644
--- a/source/opt/types.h
+++ b/source/opt/types.h
@@ -56,6 +56,7 @@
 class ForwardPointer;
 class PipeStorage;
 class NamedBarrier;
+class AccelerationStructureNV;
 
 // Abstract class for a SPIR-V type. It has a bunch of As<sublcass>() methods,
 // which is used as a way to probe the actual <subclass>.
@@ -90,6 +91,7 @@
     kForwardPointer,
     kPipeStorage,
     kNamedBarrier,
+    kAccelerationStructureNV,
   };
 
   Type(Kind k) : kind_(k) {}
@@ -170,6 +172,7 @@
   DeclareCastMethod(ForwardPointer);
   DeclareCastMethod(PipeStorage);
   DeclareCastMethod(NamedBarrier);
+  DeclareCastMethod(AccelerationStructureNV);
 #undef DeclareCastMethod
 
   bool operator==(const Type& other) const;
@@ -595,6 +598,7 @@
 DefineParameterlessType(Queue, queue);
 DefineParameterlessType(PipeStorage, pipe_storage);
 DefineParameterlessType(NamedBarrier, named_barrier);
+DefineParameterlessType(AccelerationStructureNV, acceleration_structure);
 #undef DefineParameterlessType
 
 }  // namespace analysis
diff --git a/test/opt/ir_builder.cpp b/test/opt/ir_builder.cpp
index 4c3b9b4..f800ca4 100644
--- a/test/opt/ir_builder.cpp
+++ b/test/opt/ir_builder.cpp
@@ -406,6 +406,34 @@
   Match(text, context.get());
 }
 
+TEST_F(IRBuilderTest, AccelerationStructureNV) {
+  const std::string text = R"(
+; CHECK: OpTypeAccelerationStructureNV
+OpCapability Shader
+OpCapability RayTracingNV
+OpExtension "SPV_NV_ray_tracing"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %8 "main"
+OpExecutionMode %8 OriginUpperLeft
+%1 = OpTypeVoid
+%2 = OpTypeBool
+%3 = OpTypeAccelerationStructureNV
+%7 = OpTypeFunction %1
+%8 = OpFunction %1 None %7
+%9 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  std::unique_ptr<IRContext> context =
+      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+  EXPECT_NE(nullptr, context);
+
+  InstructionBuilder builder(context.get(),
+                             &*context->module()->begin()->begin()->begin());
+  Match(text, context.get());
+}
+
 }  // namespace
 }  // namespace opt
 }  // namespace spvtools
diff --git a/test/opt/type_manager_test.cpp b/test/opt/type_manager_test.cpp
index 07a2ac4..fc9089e 100644
--- a/test/opt/type_manager_test.cpp
+++ b/test/opt/type_manager_test.cpp
@@ -156,7 +156,7 @@
   types.emplace_back(new ReserveId());
   types.emplace_back(new Queue());
 
-  // Pipe, Forward Pointer, PipeStorage, NamedBarrier
+  // Pipe, Forward Pointer, PipeStorage, NamedBarrier, AccelerationStructureNV
   types.emplace_back(new Pipe(SpvAccessQualifierReadWrite));
   types.emplace_back(new Pipe(SpvAccessQualifierReadOnly));
   types.emplace_back(new ForwardPointer(1, SpvStorageClassInput));
@@ -164,6 +164,7 @@
   types.emplace_back(new ForwardPointer(2, SpvStorageClassUniform));
   types.emplace_back(new PipeStorage());
   types.emplace_back(new NamedBarrier());
+  types.emplace_back(new AccelerationStructureNV());
 
   return types;
 }
@@ -1035,6 +1036,7 @@
 ; CHECK: OpTypeForwardPointer [[uniform_ptr]] Uniform
 ; CHECK: OpTypePipeStorage
 ; CHECK: OpTypeNamedBarrier
+; CHECK: OpTypeAccelerationStructureNV
 OpCapability Shader
 OpCapability Int64
 OpCapability Linkage
diff --git a/test/opt/types_test.cpp b/test/opt/types_test.cpp
index c11187e..7426ed7 100644
--- a/test/opt/types_test.cpp
+++ b/test/opt/types_test.cpp
@@ -88,6 +88,7 @@
 TestMultipleInstancesOfTheSameType(ForwardPointer, 10, SpvStorageClassUniform);
 TestMultipleInstancesOfTheSameType(PipeStorage);
 TestMultipleInstancesOfTheSameType(NamedBarrier);
+TestMultipleInstancesOfTheSameType(AccelerationStructureNV);
 #undef TestMultipleInstanceOfTheSameType
 
 std::vector<std::unique_ptr<Type>> GenerateAllTypes() {