Repository: KhronosGroup/SPIRV-Tools (language: python)

Issue:
Validator: False positive in OpRayQueryInitialize
This SPIR-V triggers a weird validator error. The shader is from SPIRV-Cross test suite.

```
; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 120
; Schema: 0
               OpCapability Shader
               OpCapability RayQueryKHR
               OpCapability RayTraversalPrimitiveCullingKHR
               OpExtension "SPV_KHR_ray_query"
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %4 "main" %10 %13 %20 %46
               OpExecutionModeId %4 LocalSizeId %7 %7 %7
               OpSource GLSL 460
               OpSourceExtension "GL_EXT_ray_flags_primitive_culling"
               OpSourceExtension "GL_EXT_ray_query"
               OpSourceExtension "GL_EXT_ray_tracing"
               OpName %4 "main"
               OpName %10 "q"
               OpName %13 "AS"
               OpName %18 "Params"
               OpMemberName %18 0 "ray_flags"
               OpMemberName %18 1 "cull_mask"
               OpMemberName %18 2 "origin"
               OpMemberName %18 3 "tmin"
               OpMemberName %18 4 "dir"
               OpMemberName %18 5 "tmax"
               OpMemberName %18 6 "thit"
               OpMemberName %18 7 "bda"
               OpName %20 ""
               OpName %46 "q2"
               OpName %67 "res"
               OpName %75 "fval"
               OpName %78 "type"
               OpName %82 "fvals"
               OpName %94 "ival"
               OpName %116 "matrices"
               OpDecorate %13 DescriptorSet 0
               OpDecorate %13 Binding 0
               OpMemberDecorate %18 0 Offset 0
               OpMemberDecorate %18 1 Offset 4
               OpMemberDecorate %18 2 Offset 16
               OpMemberDecorate %18 3 Offset 28
               OpMemberDecorate %18 4 Offset 32
               OpMemberDecorate %18 5 Offset 44
               OpMemberDecorate %18 6 Offset 48
               OpMemberDecorate %18 7 Offset 56
               OpDecorate %18 Block
               OpDecorate %20 DescriptorSet 0
               OpDecorate %20 Binding 1
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 0
          %7 = OpConstant %6 1
          %8 = OpTypeRayQueryKHR
          %9 = OpTypePointer Private %8
         %10 = OpVariable %9 Private
         %11 = OpTypeAccelerationStructureKHR
         %12 = OpTypePointer UniformConstant %11
         %13 = OpVariable %12 UniformConstant
         %15 = OpTypeFloat 32
         %16 = OpTypeVector %15 3
         %17 = OpTypeVector %6 2
         %18 = OpTypeStruct %6 %6 %16 %15 %16 %15 %15 %17
         %19 = OpTypePointer Uniform %18
         %20 = OpVariable %19 Uniform
         %21 = OpTypeInt 32 1
         %22 = OpConstant %21 0
         %23 = OpTypePointer Uniform %6
         %26 = OpConstant %21 1
         %29 = OpConstant %21 2
         %30 = OpTypePointer Uniform %16
         %33 = OpConstant %21 3
         %34 = OpTypePointer Uniform %15
         %37 = OpConstant %21 4
         %40 = OpConstant %21 5
         %43 = OpConstant %6 2
         %44 = OpTypeArray %8 %43
         %45 = OpTypePointer Private %44
         %46 = OpVariable %45 Private
         %48 = OpConstant %21 7
         %49 = OpTypePointer Uniform %17
         %65 = OpTypeBool
         %66 = OpTypePointer Function %65
         %70 = OpConstant %21 6
         %74 = OpTypePointer Function %15
         %77 = OpTypePointer Function %6
         %81 = OpTypePointer Function %16
         %86 = OpConstantTrue %65
         %91 = OpConstantFalse %65
         %93 = OpTypePointer Function %21
        %103 = OpTypeVector %15 2
        %105 = OpConstant %6 0
        %114 = OpTypeMatrix %16 4
        %115 = OpTypePointer Function %114
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %67 = OpVariable %66 Function
         %75 = OpVariable %74 Function
         %78 = OpVariable %77 Function
         %82 = OpVariable %81 Function
         %94 = OpVariable %93 Function
        %116 = OpVariable %115 Function
         %14 = OpLoad %11 %13
         %24 = OpAccessChain %23 %20 %22
         %25 = OpLoad %6 %24
         %27 = OpAccessChain %23 %20 %26
         %28 = OpLoad %6 %27
         %31 = OpAccessChain %30 %20 %29
         %32 = OpLoad %16 %31
         %35 = OpAccessChain %34 %20 %33
         %36 = OpLoad %15 %35
         %38 = OpAccessChain %30 %20 %37
         %39 = OpLoad %16 %38
         %41 = OpAccessChain %34 %20 %40
         %42 = OpLoad %15 %41
               OpRayQueryInitializeKHR %10 %14 %25 %28 %32 %36 %39 %42
         %47 = OpAccessChain %9 %46 %26
         %50 = OpAccessChain %49 %20 %48
         %51 = OpLoad %17 %50
         %52 = OpConvertUToAccelerationStructureKHR %11 %51
         %53 = OpAccessChain %23 %20 %22
         %54 = OpLoad %6 %53
         %55 = OpAccessChain %23 %20 %26
         %56 = OpLoad %6 %55
         %57 = OpAccessChain %30 %20 %29
         %58 = OpLoad %16 %57
         %59 = OpAccessChain %34 %20 %33
         %60 = OpLoad %15 %59
         %61 = OpAccessChain %30 %20 %37
         %62 = OpLoad %16 %61
         %63 = OpAccessChain %34 %20 %40
         %64 = OpLoad %15 %63
               OpRayQueryInitializeKHR %47 %52 %54 %56 %58 %60 %62 %64
         %68 = OpRayQueryProceedKHR %65 %10
               OpStore %67 %68
         %69 = OpAccessChain %9 %46 %22
               OpRayQueryTerminateKHR %69
         %71 = OpAccessChain %34 %20 %70
         %72 = OpLoad %15 %71
               OpRayQueryGenerateIntersectionKHR %10 %72
         %73 = OpAccessChain %9 %46 %26
               OpRayQueryConfirmIntersectionKHR %73
         %76 = OpRayQueryGetRayTMinKHR %15 %10
               OpStore %75 %76
         %79 = OpAccessChain %9 %46 %22
         %80 = OpRayQueryGetRayFlagsKHR %6 %79
               OpStore %78 %80
         %83 = OpRayQueryGetWorldRayDirectionKHR %16 %10
               OpStore %82 %83
         %84 = OpRayQueryGetWorldRayOriginKHR %16 %10
               OpStore %82 %84
         %85 = OpAccessChain %9 %46 %26
         %87 = OpRayQueryGetIntersectionTypeKHR %6 %85 %26
               OpStore %78 %87
         %88 = OpAccessChain %9 %46 %26
         %89 = OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %65 %88
               OpStore %67 %89
         %90 = OpAccessChain %9 %46 %26
         %92 = OpRayQueryGetIntersectionTKHR %15 %90 %22
               OpStore %75 %92
         %95 = OpRayQueryGetIntersectionInstanceCustomIndexKHR %21 %10 %26
               OpStore %94 %95
         %96 = OpAccessChain %9 %46 %22
         %97 = OpRayQueryGetIntersectionInstanceIdKHR %21 %96 %22
               OpStore %94 %97
         %98 = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %6 %10 %26
               OpStore %78 %98
         %99 = OpAccessChain %9 %46 %26
        %100 = OpRayQueryGetIntersectionGeometryIndexKHR %21 %99 %22
               OpStore %94 %100
        %101 = OpRayQueryGetIntersectionPrimitiveIndexKHR %21 %10 %26
               OpStore %94 %101
        %102 = OpAccessChain %9 %46 %22
        %104 = OpRayQueryGetIntersectionBarycentricsKHR %103 %102 %22
        %106 = OpAccessChain %74 %82 %105
        %107 = OpCompositeExtract %15 %104 0
               OpStore %106 %107
        %108 = OpAccessChain %74 %82 %7
        %109 = OpCompositeExtract %15 %104 1
               OpStore %108 %109
        %110 = OpRayQueryGetIntersectionFrontFaceKHR %65 %10 %26
               OpStore %67 %110
        %111 = OpRayQueryGetIntersectionObjectRayDirectionKHR %16 %10 %22
               OpStore %82 %111
        %112 = OpAccessChain %9 %46 %22
        %113 = OpRayQueryGetIntersectionObjectRayOriginKHR %16 %112 %26
               OpStore %82 %113
        %117 = OpRayQueryGetIntersectionObjectToWorldKHR %114 %10 %22
               OpStore %116 %117
        %118 = OpAccessChain %9 %46 %26
        %119 = OpRayQueryGetIntersectionWorldToObjectKHR %114 %118 %26
               OpStore %116 %119
               OpReturn
               OpFunctionEnd
```

reports in validator:

```
error: line 129: Ray Query must be a memory object declaration
  OpRayQueryInitializeKHR %47 %52 %54 %56 %58 %60 %62 %64
```

The shader is using an array of ray query objects, so the pattern is OpVariable -> OpAccessChain -> RayQueryInitialize.
This used to validate fine in 4c456f7da67c5437a6fb7d4d20d78e2a5ae2acf2. I can't find any spec text saying this is not allowed.


Discussion / hints:
Finding the same issue with several CTS shaders after updating the SPIR-V tools reference to get the recent EmitMeshTasksEXT changes. Also using an array of ray query objects. Example:

```
; SPIR-V
; Version: 1.4
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 94
; Schema: 0
               OpCapability Shader
               OpCapability RayQueryKHR
               OpExtension "SPV_KHR_ray_query"
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main" %inputBlock %gl_LocalInvocationID %rayQueries %topLevelAS %outputBlock
               OpExecutionMode %main LocalSize 48 1 1
               OpSource GLSL 460
               OpSourceExtension "GL_EXT_ray_query"
               OpSourceExtension "GL_EXT_ray_tracing"
               OpName %main "main"
               OpName %InputData "InputData"
               OpMemberName %InputData 0 "goodQueryIndex"
               OpMemberName %InputData 1 "proceedQueryIndex"
               OpName %inputValues "inputValues"
               OpName %InputData_0 "InputData"
               OpMemberName %InputData_0 0 "goodQueryIndex"
               OpMemberName %InputData_0 1 "proceedQueryIndex"
               OpName %InputBlock "InputBlock"
               OpMemberName %InputBlock 0 "inputData"
               OpName %inputBlock "inputBlock"
               OpName %gl_LocalInvocationID "gl_LocalInvocationID"
               OpName %i "i"
               OpName %origin "origin"
               OpName %rayQueries "rayQueries"
               OpName %topLevelAS "topLevelAS"
               OpName %OutputBlock "OutputBlock"
               OpMemberName %OutputBlock 0 "outputData"
               OpName %outputBlock "outputBlock"
               OpMemberDecorate %InputData_0 0 Offset 0
               OpMemberDecorate %InputData_0 1 Offset 4
               OpDecorate %_runtimearr_InputData_0 ArrayStride 8
               OpMemberDecorate %InputBlock 0 Offset 0
               OpDecorate %InputBlock Block
               OpDecorate %inputBlock DescriptorSet 0
               OpDecorate %inputBlock Binding 1
               OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
               OpDecorate %topLevelAS DescriptorSet 0
               OpDecorate %topLevelAS Binding 0
               OpDecorate %_runtimearr_uint ArrayStride 4
               OpMemberDecorate %OutputBlock 0 Offset 0
               OpDecorate %OutputBlock Block
               OpDecorate %outputBlock DescriptorSet 0
               OpDecorate %outputBlock Binding 2
               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %uint = OpTypeInt 32 0
  %InputData = OpTypeStruct %uint %uint
%_ptr_Function_InputData = OpTypePointer Function %InputData
%InputData_0 = OpTypeStruct %uint %uint
%_runtimearr_InputData_0 = OpTypeRuntimeArray %InputData_0
 %InputBlock = OpTypeStruct %_runtimearr_InputData_0
%_ptr_StorageBuffer_InputBlock = OpTypePointer StorageBuffer %InputBlock
 %inputBlock = OpVariable %_ptr_StorageBuffer_InputBlock StorageBuffer
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
     %v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
     %uint_0 = OpConstant %uint 0
%_ptr_Input_uint = OpTypePointer Input %uint
%_ptr_StorageBuffer_InputData_0 = OpTypePointer StorageBuffer %InputData_0
%_ptr_Function_int = OpTypePointer Function %int
    %uint_48 = OpConstant %uint 48
       %bool = OpTypeBool
      %float = OpTypeFloat 32
    %v3float = OpTypeVector %float 3
%_ptr_Function_v3float = OpTypePointer Function %v3float
%_ptr_Function_uint = OpTypePointer Function %uint
    %float_0 = OpConstant %float 0
         %51 = OpConstantComposite %v3float %float_0 %float_0 %float_0
    %float_5 = OpConstant %float 5
         %53 = OpConstantComposite %v3float %float_5 %float_5 %float_0
         %55 = OpTypeRayQueryKHR
%_arr_55_uint_48 = OpTypeArray %55 %uint_48
%_ptr_Private__arr_55_uint_48 = OpTypePointer Private %_arr_55_uint_48
 %rayQueries = OpVariable %_ptr_Private__arr_55_uint_48 Private
%_ptr_Private_55 = OpTypePointer Private %55
         %62 = OpTypeAccelerationStructureKHR
%_ptr_UniformConstant_62 = OpTypePointer UniformConstant %62
 %topLevelAS = OpVariable %_ptr_UniformConstant_62 UniformConstant
   %uint_255 = OpConstant %uint 255
%float_0_100000001 = OpConstant %float 0.100000001
    %float_1 = OpConstant %float 1
         %70 = OpConstantComposite %v3float %float_0 %float_0 %float_1
   %float_10 = OpConstant %float 10
      %int_1 = OpConstant %int 1
%_runtimearr_uint = OpTypeRuntimeArray %uint
%OutputBlock = OpTypeStruct %_runtimearr_uint
%_ptr_StorageBuffer_OutputBlock = OpTypePointer StorageBuffer %OutputBlock
%outputBlock = OpVariable %_ptr_StorageBuffer_OutputBlock StorageBuffer
     %uint_1 = OpConstant %uint 1
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_48 %uint_1 %uint_1
       %main = OpFunction %void None %3
          %5 = OpLabel
%inputValues = OpVariable %_ptr_Function_InputData Function
          %i = OpVariable %_ptr_Function_int Function
     %origin = OpVariable %_ptr_Function_v3float Function
         %22 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0
         %23 = OpLoad %uint %22
         %25 = OpAccessChain %_ptr_StorageBuffer_InputData_0 %inputBlock %int_0 %23
         %26 = OpLoad %InputData_0 %25
         %27 = OpCopyLogical %InputData %26
               OpStore %inputValues %27
               OpStore %i %int_0
               OpBranch %30
         %30 = OpLabel
               OpLoopMerge %32 %33 None
               OpBranch %34
         %34 = OpLabel
         %35 = OpLoad %int %i
         %36 = OpBitcast %uint %35
         %39 = OpULessThan %bool %36 %uint_48
               OpBranchConditional %39 %31 %32
         %31 = OpLabel
         %44 = OpLoad %int %i
         %45 = OpBitcast %uint %44
         %47 = OpAccessChain %_ptr_Function_uint %inputValues %int_0
         %48 = OpLoad %uint %47
         %49 = OpIEqual %bool %45 %48
         %54 = OpSelect %v3float %49 %51 %53
               OpStore %origin %54
         %59 = OpLoad %int %i
         %61 = OpAccessChain %_ptr_Private_55 %rayQueries %59
         %65 = OpLoad %62 %topLevelAS
         %67 = OpLoad %v3float %origin
               OpRayQueryInitializeKHR %61 %65 %uint_0 %uint_255 %67 %float_0_100000001 %70 %float_10
               OpBranch %33
         %33 = OpLabel
         %72 = OpLoad %int %i
         %74 = OpIAdd %int %72 %int_1
               OpStore %i %74
               OpBranch %30
         %32 = OpLabel
               OpBranch %75
         %75 = OpLabel
               OpLoopMerge %77 %78 None
               OpBranch %79
         %79 = OpLabel
         %80 = OpAccessChain %_ptr_Function_uint %inputValues %int_1
         %81 = OpLoad %uint %80
         %82 = OpAccessChain %_ptr_Private_55 %rayQueries %81
         %83 = OpRayQueryProceedKHR %bool %82
               OpBranchConditional %83 %76 %77
         %76 = OpLabel
         %88 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0
         %89 = OpLoad %uint %88
         %92 = OpAccessChain %_ptr_StorageBuffer_uint %outputBlock %int_0 %89
               OpStore %92 %uint_1
               OpBranch %78
         %78 = OpLabel
               OpBranch %75
         %77 = OpLabel
               OpReturn
               OpFunctionEnd
```
I bisected the problem and found 4c456f7da67c5437a6fb7d4d20d78e2a5ae2acf2 to have issues too. It appears the problem was introduced the first time ray queries were validated in e4cfa190dfa144f1db5bcca2a6b11a6ba429824d.
sorry didn't see this issue earlier, in the spec I read 

>  Ray Query is a pointer to **the** ray query to initialize.

as it would ever be a single object, didn't factor it could be in an array... thanks for the PR to fix this

Fix patch:
diff --git a/source/val/validate_ray_query.cpp b/source/val/validate_ray_query.cpp
index f92bf016a3..b553449d0b 100644
--- a/source/val/validate_ray_query.cpp
+++ b/source/val/validate_ray_query.cpp
@@ -28,8 +28,10 @@ spv_result_t ValidateRayQueryPointer(ValidationState_t& _,
                                      uint32_t ray_query_index) {
   const uint32_t ray_query_id = inst->GetOperandAs<uint32_t>(ray_query_index);
   auto variable = _.FindDef(ray_query_id);
-  if (!variable || (variable->opcode() != SpvOpVariable &&
-                    variable->opcode() != SpvOpFunctionParameter)) {
+  const auto var_opcode = variable->opcode();
+  if (!variable ||
+      (var_opcode != SpvOpVariable && var_opcode != SpvOpFunctionParameter &&
+       var_opcode != SpvOpAccessChain)) {
     return _.diag(SPV_ERROR_INVALID_DATA, inst)
            << "Ray Query must be a memory object declaration";
   }


Test patch:
diff --git a/test/val/val_ray_query_test.cpp b/test/val/val_ray_query_test.cpp
index e9b9696373..1541c74535 100644
--- a/test/val/val_ray_query_test.cpp
+++ b/test/val/val_ray_query_test.cpp
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "gmock/gmock.h"
+#include "spirv-tools/libspirv.h"
 #include "test/val/val_fixtures.h"
 
 namespace spvtools {
@@ -573,6 +574,58 @@ OpRayQueryGenerateIntersectionKHR %ray_query %u32_0
               HasSubstr("Hit T must be a 32-bit float scalar"));
 }
 
+TEST_F(ValidateRayQuery, RayQueryArraySuccess) {
+  // This shader is slightly different to the ones above, so it doesn't reuse
+  // the shader code generator.
+  const std::string shader = R"(
+                       OpCapability Shader
+                       OpCapability RayQueryKHR
+                       OpExtension "SPV_KHR_ray_query"
+                       OpMemoryModel Logical GLSL450
+                       OpEntryPoint GLCompute %main "main"
+                       OpExecutionMode %main LocalSize 1 1 1
+                       OpSource GLSL 460
+                       OpDecorate %topLevelAS DescriptorSet 0
+                       OpDecorate %topLevelAS Binding 0
+                       OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
+               %void = OpTypeVoid
+               %func = OpTypeFunction %void
+          %ray_query = OpTypeRayQueryKHR
+               %uint = OpTypeInt 32 0
+             %uint_2 = OpConstant %uint 2
+    %ray_query_array = OpTypeArray %ray_query %uint_2
+%ptr_ray_query_array = OpTypePointer Private %ray_query_array
+         %rayQueries = OpVariable %ptr_ray_query_array Private
+                %int = OpTypeInt 32 1
+              %int_0 = OpConstant %int 0
+      %ptr_ray_query = OpTypePointer Private %ray_query
+       %accel_struct = OpTypeAccelerationStructureKHR
+   %ptr_accel_struct = OpTypePointer UniformConstant %accel_struct
+         %topLevelAS = OpVariable %ptr_accel_struct UniformConstant
+             %uint_0 = OpConstant %uint 0
+           %uint_255 = OpConstant %uint 255
+              %float = OpTypeFloat 32
+            %v3float = OpTypeVector %float 3
+            %float_0 = OpConstant %float 0
+          %vec3_zero = OpConstantComposite %v3float %float_0 %float_0 %float_0
+            %float_1 = OpConstant %float 1
+      %vec3_xy_0_z_1 = OpConstantComposite %v3float %float_0 %float_0 %float_1
+           %float_10 = OpConstant %float 10
+             %v3uint = OpTypeVector %uint 3
+             %uint_1 = OpConstant %uint 1
+   %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+               %main = OpFunction %void None %func
+         %main_label = OpLabel
+    %first_ray_query = OpAccessChain %ptr_ray_query %rayQueries %int_0
+     %topLevelAS_val = OpLoad %accel_struct %topLevelAS
+                       OpRayQueryInitializeKHR %first_ray_query %topLevelAS_val %uint_0 %uint_255 %vec3_zero %float_0 %vec3_xy_0_z_1 %float_10
+                       OpReturn
+                       OpFunctionEnd
+)";
+  CompileSuccessfully(shader);
+  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
 }  // namespace
 }  // namespace val
 }  // namespace spvtools