Skip to content

Invalid const buffer reference function parameter allowed (crashes driver) #4156

@glebov-andrey

Description

@glebov-andrey

Hi,

While debugging a driver crash (AMD Windows driver, deep inside amdvlk64.dll in the vkCreateComputePipelines function), I found that the reason was a const-qualified buffer reference type function parameter.
The GLSL_EXT_buffer_reference spec explicitly disallows const-qualified buffer reference types here: https://github.com/KhronosGroup/GLSL/blob/38037bb58882e014e8270000c5533d890a79fa63/extensions/ext/GLSL_EXT_buffer_reference.txt#L93-L99
glslang (as of 16.1.0) generates different SPIR-V depending on the parameter's const-qualification which is presumably what leads to the crash.

Here's an example:

#version 460

#extension GL_EXT_buffer_reference : require
#extension GL_EXT_shader_explicit_arithmetic_types : require

layout(buffer_reference, std430, buffer_reference_align = 16) buffer MyBufferRef {
    vec4 data;
};

void func(
#ifdef ADD_CONST
    const
#endif
    MyBufferRef buffer_ref) {
}

void main() {
    func(MyBufferRef(0ul));
}

Compiler commands:

glslang --target-env vulkan1.3 const-buf-ref.frag -o buf-ref.frag.spv
glslang --target-env vulkan1.3 const-buf-ref.frag -o buf-ref-const.frag.spv -DADD_CONST
spirv-dis buf-ref.frag.spv > buf-ref.frag.spv.txt
spirv-dis buf-ref-const.frag.spv > buf-ref-const.frag.spv.txt

SPIR-V diff (WITHOUT and WITH const):

diff --git "buf-ref.frag.spv.txt" "buf-ref-const.frag.spv.txt"
index 6fc622b..99990cd 100644
--- "a/buf-ref.frag.spv.txt"
+++ "b/buf-ref-const.frag.spv.txt"
@@ -1,49 +1,44 @@
 ; SPIR-V
 ; Version: 1.6
 ; Generator: Khronos Glslang Reference Front End; 11
-; Bound: 20
+; Bound: 18
 ; Schema: 0
                OpCapability Shader
                OpCapability Int64
                OpCapability PhysicalStorageBufferAddresses
           %1 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel PhysicalStorageBuffer64 GLSL450
                OpEntryPoint Fragment %main "main"
                OpExecutionMode %main OriginUpperLeft
                OpSource GLSL 460
                OpSourceExtension "GL_EXT_buffer_reference"
                OpSourceExtension "GL_EXT_shader_explicit_arithmetic_types"
                OpName %main "main"
                OpName %MyBufferRef "MyBufferRef"
                OpMemberName %MyBufferRef 0 "data"
                OpName %func_1_ "func(1;"
                OpName %buffer_ref "buffer_ref"
-               OpName %param "param"
                OpDecorate %MyBufferRef Block
                OpMemberDecorate %MyBufferRef 0 Offset 0
-               OpDecorate %buffer_ref AliasedPointer
-               OpDecorate %param AliasedPointer
+               OpDecorate %buffer_ref Aliased
        %void = OpTypeVoid
           %3 = OpTypeFunction %void
                OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_MyBufferRef PhysicalStorageBuffer
       %float = OpTypeFloat 32
     %v4float = OpTypeVector %float 4
 %MyBufferRef = OpTypeStruct %v4float
 %_ptr_PhysicalStorageBuffer_MyBufferRef = OpTypePointer PhysicalStorageBuffer %MyBufferRef
-%_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef = OpTypePointer Function %_ptr_PhysicalStorageBuffer_MyBufferRef
-         %11 = OpTypeFunction %void %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef
+         %10 = OpTypeFunction %void %_ptr_PhysicalStorageBuffer_MyBufferRef
       %ulong = OpTypeInt 64 0
     %ulong_0 = OpConstant %ulong 0
        %main = OpFunction %void None %3
           %5 = OpLabel
-      %param = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef Function
-         %17 = OpBitcast %_ptr_PhysicalStorageBuffer_MyBufferRef %ulong_0
-               OpStore %param %17
-         %19 = OpFunctionCall %void %func_1_ %param
+         %16 = OpBitcast %_ptr_PhysicalStorageBuffer_MyBufferRef %ulong_0
+         %17 = OpFunctionCall %void %func_1_ %16
                OpReturn
                OpFunctionEnd
-    %func_1_ = OpFunction %void None %11
- %buffer_ref = OpFunctionParameter %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef
-         %14 = OpLabel
+    %func_1_ = OpFunction %void None %10
+ %buffer_ref = OpFunctionParameter %_ptr_PhysicalStorageBuffer_MyBufferRef
+         %13 = OpLabel
                OpReturn
                OpFunctionEnd

Metadata

Metadata

Assignees

Labels

GLSL/ESSLSPIR-Vsev:miscompileGiven a valid input, glslang produces incorrect or invalid SPIR-V

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions