[BUG] Compiler issues internal error: "offset for relative array access outside supported range"

Bug report and files:

https://github.com/mc-imperial/shader-compiler-bugs/issues/15

Fragment shader:

#version 440

void main()
{
    vec3 dir = vec3(1.0);
    vec4 A[5] = vec4[5]((vec4(1.0)), (vec4(1.0)), (vec4(1.0)), (vec4(1.0)), mod(vec4(1.0), vec4(3.7, 1.0, 8.1, 2.3)));
    int i = (floatBitsToInt(1.0) + clamp(ivec4(72114, 6043, 47109, 71450), ivec4(47148, 21410, 1, 79446), ivec4(1))[3]);
    vec2 p = mod(vec2(1.0) * A[i].y, 2.0) - 1.0;
    float r = length(p);
    vec4 col = vec4(0., 0., 0., 0.);
    if(r < 0.70) {
        col = vec4(1.0);
    }
    dir = mix(vec3(1.0), col.rgb, 1.0);
    for(int r = 0; 1 < 12; r ++) {
       dir += vec3(1.0);
    }
}

Link error log:

Fragment info
-------------
Internal error: assembly compile error for fragment shader at offset 544:
-- error message --
line 21, column 30:  error: offset for relative array access outside supported range
-- internal assembly text --
!!NVfp5.0
OPTION NV_bindless_texture;
# cgc version 3.4.0001, build date Oct  1 2016
# command line args:
#vendor NVIDIA Corporation
#version 3.4.0.1 COP Build Date Oct  1 2016
#profile gp5fp
#program main
#semantic @TMP34 : __LOCAL
#var float4 @TMP34[0] :  : local[0] : -1 : 1
TEMP R0;
TEMP RC, HC;
TEMP lmem[5];
MOV.F lmem[0], {1, 0, 0, 0}.x;
MOV.F lmem[1], {1, 0, 0, 0}.x;
MOV.F lmem[2], {1, 0, 0, 0}.x;
MOV.F lmem[3], {1, 0, 0, 0}.x;
MOV.F R0.x, {1, 0, 0, 0};
MOV.U R0.x, R0;
MOV.F lmem[4], {1, 0, 0, 0}.xyxx;
MOV.F R0.y, lmem[R0.x + 79446].y;
MUL.F R0.x, R0.y, {0.5, 0, 0, 0};
FLR.F R0.x, R0;
MAD.F R0.x, -R0, {2, 0, 0, 0}, R0.y;
ADD.F R0.x, R0, {-1, 0, 0, 0};
DP2.F R0.x, R0.x, R0.x;
RSQ.F R0.x, R0.x;
RCP.F R0.x, R0.x;
SLT.F R0.x, R0, {0.699999988, 0, 0, 0};
TRUNC.U.CC HC.x, R0;
IF    NE.x;
ENDIF;
REP.S ;
SEQ.U.CC HC.x, {1, 0, 0, 0}, {0, 0, 0, 0};
BRK   (NE.x);
ENDREP;
END
# 23 instructions, 1 R-regs

Note that the shader is accepted by glslangValidator and by a recent Intel driver.

  1. Operating system version.

Windows 10

  1. Graphics hardware.

GeForce GTX 770. Driver: 373.06

  1. Reproducer project.
    We have provided the fragment shader at the above link.

  2. Description of single steps to reproduce the problem.
    Compile and link the fragment shader.

  3. Description of the expected result.
    No link error.

Thanks for the report. We have filed an internal bug to track this issue.

Hello,

I have the same issue, is there any update about this bug ?

Please find my minimal code example which reproduces the bug :

Vertex shader in HLSL:

ByteAddressBuffer VertexBuffer : register(t0);

uint VS_Forward(uint _vertexId)
{
    uint offset = 4 * _vertexId;
    uint3 tmp = VertexBuffer.Load3(offset);

    return tmp.x + tmp.y + tmp.z;
}

Note that you can make 3 seperate Load() to have the same behavior without having the error.

Link error log:

Vulkan validation layer Driver, code 2: Vertex info
-----------
Internal error: assembly compile error for vertex shader at offset 755:
-- error message --
line 23, column 27:  error: offset for relative array access outside supported range
line 24, column 27:  error: offset for relative array access outside supported range
-- internal assembly text --
!!NVvp5.0
OPTION NV_internal;
OPTION NV_bindless_texture;
# cgc version 3.4.0001, build date Oct 12 2017
# command line args: 
#vendor NVIDIA Corporation
#version 3.4.0.1 COP Build Date Oct 12 2017
#profile gp5vp
#program VS_Forward
#semantic VertexBuffer.VertexBuffer.28 : SBO_BUFFER[-1]
#semantic @TMP0 : __LOCAL
#var int gl_VertexIndex : $vin.VERTEXINDEX : VERTEXIDX : -1 : 1
#var uint VertexBuffer.28.@data[0] :  : c[0] : -1 : 0
#var uint @entryPointOutput.62 : $vout.ATTR0 : ATTR0 : -1 : 1
#var uint @TMP0.@data[0] :  : lmem0[0] : -1 : 1
OUTPUT result_attrib[] = { result.attrib[0..0] };
TEMP R0, R1, R2;
TEMP T;
TEMP lmem0[1];
MUL.U R0.x, vertex.vertexIndex, {4, 0, 0, 0};
SHR.U R0.x, R0, {2, 0, 0, 0}.x;
MOV.U R0.y, R0.x;
MOV.U R0.x, lmem0[R0.y + 2].x;
MOV.U R1.x, lmem0[R0.y + 1].x;
MOV.U R2.x, lmem0[R0.y].x;
ADD.U R0.y, R2.x, R1.x;
ADD.U result.attrib[0].x, R0.y, R0;
END
# 8 instructions, 3 R-regs

Generated spirv bytecode:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 2
; Bound: 94
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %VS_Forward "VS_Forward" %vertexID %_entryPointOutput
               OpSource HLSL 500
               OpName %VS_Forward "VS_Forward"
               OpName %VertexBuffer "VertexBuffer"
               OpMemberName %VertexBuffer 0 "@data"
               OpName %VertexBuffer_0 "VertexBuffer"
               OpName %vertexID "vertexID"
               OpName %_entryPointOutput "@entryPointOutput"
               OpDecorate %_runtimearr_uint ArrayStride 4
               OpMemberDecorate %VertexBuffer 0 NonWritable
               OpMemberDecorate %VertexBuffer 0 Offset 0
               OpDecorate %VertexBuffer BufferBlock
               OpDecorate %VertexBuffer_0 DescriptorSet 0
               OpDecorate %VertexBuffer_0 Binding 0
               OpDecorate %vertexID BuiltIn VertexIndex
               OpDecorate %_entryPointOutput Location 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %uint = OpTypeInt 32 0
     %uint_4 = OpConstant %uint 4
        %int = OpTypeInt 32 1
      %int_2 = OpConstant %int 2
%_runtimearr_uint = OpTypeRuntimeArray %uint
%VertexBuffer = OpTypeStruct %_runtimearr_uint
%_ptr_Uniform_VertexBuffer = OpTypePointer Uniform %VertexBuffer
%VertexBuffer_0 = OpVariable %_ptr_Uniform_VertexBuffer Uniform
      %int_0 = OpConstant %int 0
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %int_1 = OpConstant %int 1
%_ptr_Input_uint = OpTypePointer Input %uint
   %vertexID = OpVariable %_ptr_Input_uint Input
%_ptr_Output_uint = OpTypePointer Output %uint
%_entryPointOutput = OpVariable %_ptr_Output_uint Output
 %VS_Forward = OpFunction %void None %3
          %5 = OpLabel
         %60 = OpLoad %uint %vertexID
         %71 = OpIMul %uint %uint_4 %60
         %73 = OpShiftRightLogical %int %71 %int_2
         %75 = OpAccessChain %_ptr_Uniform_uint %VertexBuffer_0 %int_0 %73
         %76 = OpLoad %uint %75
         %78 = OpIAdd %int %73 %int_1
         %79 = OpAccessChain %_ptr_Uniform_uint %VertexBuffer_0 %int_0 %78
         %80 = OpLoad %uint %79
         %82 = OpIAdd %int %73 %int_2
         %83 = OpAccessChain %_ptr_Uniform_uint %VertexBuffer_0 %int_0 %82
         %84 = OpLoad %uint %83
         %90 = OpIAdd %uint %76 %80
         %93 = OpIAdd %uint %90 %84
               OpStore %_entryPointOutput %93
               OpReturn
               OpFunctionEnd

You can see that I am compiling HLSL with glslangValidator.exe, the spirv bytecode seems fine and is accepted by glslangValidator and the vulkan debug layer.

OS version: Windows 10 Enterprise, 64-bit
Graphics hardware: NVIDIA GeForce GTX 970
Graphics driver: 388.00

+1 on that

System:
Windows 10 Enterprise, 64 bit
NVIDIA GeForce GTX 1070
Driver: 388.71

bump.
Windows 10 home, 64 bit
NVIDIA GeForce GTX 1070
Driver: 461.72

-----------
Internal error: assembly compile error for vertex shader at offset 738:
-- error message --
line 23, column 9:  error: invalid parameter array size
line 30, column 46:  error: offset for relative array access outside supported range
line 32, column 47:  error: offset for relative array access outside supported range
line 36, column 38:  error: offset for relative array access outside supported range
line 37, column 30:  error: offset for relative array access outside supported range
line 39, column 61:  error: offset for relative array access outside supported range
-- internal assembly text --
!!NVvp5.0
OPTION NV_internal;
OPTION NV_bindless_texture;
# cgc version 3.4.0001, build date Feb 23 2021
# command line args:
#vendor NVIDIA Corporation
#version 3.4.0.1 COP Build Date Feb 23 2021
#profile gp5vp
#program main
#semantic uScreen
#semantic uMVP
#semantic uUV
#semantic uColor
#var int gl_InstanceID : $vin.INSTANCEID : INSTANCEID : -1 : 1
#var float4 gl_Position : $vout.POSITION :