Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect codegen when there is redundant float16_t conversion #5701

Closed
FanShupei opened this issue Jun 4, 2024 · 1 comment
Closed

Incorrect codegen when there is redundant float16_t conversion #5701

FanShupei opened this issue Jun 4, 2024 · 1 comment

Comments

@FanShupei
Copy link

For background, you may see google/shaderc#1418

I just understand this is actually a glslang bug, so I raise the issue here.

For the compute shader, glslang generates ill-formed spirv binary, demonstrated by the following commands

$ glslang --target-env vulkan1.3 issue.comp
$ spirv-val comp.spv
error: line 65: Expected input to have different bit width from Result Type: FConvert
  %33 = OpFConvert %half %31
#version 450
#extension GL_EXT_shader_16bit_storage : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

#define TYPE float16_t // or 'int64_t', 'uint16_t', also generated ill-formed spirv
// #define TYPE float, int, uint, these are fine
layout(binding = 0) readonly buffer A { TYPE data_a[]; };
layout(binding = 1) writeonly buffer D { TYPE data_d[]; };

void main() {
    const uint i = gl_GlobalInvocationID.x;
    data_d[i] = TYPE(data_a[i]);
}

I take a look at the disassembly, it is indeed incorrect. The spec on OPFConvert says that "The component width must not equal the component width in Result Type.", so the op actually should be eliminated.

; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 37
; Schema: 0
               OpCapability Shader
               OpCapability StorageBuffer16BitAccess
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID %_ %__0
               OpExecutionMode %main LocalSize 1 1 1
               OpSource GLSL 450
               OpSourceExtension "GL_EXT_shader_16bit_storage"
               OpName %main "main"
               OpName %i "i"
               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
               OpName %D "D"
               OpMemberName %D 0 "data_d"
               OpName %_ ""
               OpName %A "A"
               OpMemberName %A 0 "data_a"
               OpName %__0 ""
               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
               OpDecorate %_runtimearr_half ArrayStride 2
               OpMemberDecorate %D 0 NonReadable
               OpMemberDecorate %D 0 Offset 0
               OpDecorate %D Block
               OpDecorate %_ DescriptorSet 0
               OpDecorate %_ Binding 1
               OpDecorate %_runtimearr_half_0 ArrayStride 2
               OpMemberDecorate %A 0 NonWritable
               OpMemberDecorate %A 0 Offset 0
               OpDecorate %A Block
               OpDecorate %__0 DescriptorSet 0
               OpDecorate %__0 Binding 0
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
     %v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
     %uint_0 = OpConstant %uint 0
%_ptr_Input_uint = OpTypePointer Input %uint
       %half = OpTypeFloat 16
%_runtimearr_half = OpTypeRuntimeArray %half
          %D = OpTypeStruct %_runtimearr_half
%_ptr_StorageBuffer_D = OpTypePointer StorageBuffer %D
          %_ = OpVariable %_ptr_StorageBuffer_D StorageBuffer
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_runtimearr_half_0 = OpTypeRuntimeArray %half
          %A = OpTypeStruct %_runtimearr_half_0
%_ptr_StorageBuffer_A = OpTypePointer StorageBuffer %A
        %__0 = OpVariable %_ptr_StorageBuffer_A StorageBuffer
%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
      %float = OpTypeFloat 32
     %uint_1 = OpConstant %uint 1
         %36 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %main = OpFunction %void None %3
          %5 = OpLabel
          %i = OpVariable %_ptr_Function_uint Function
         %14 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
         %15 = OpLoad %uint %14
               OpStore %i %15
         %23 = OpLoad %uint %i
         %28 = OpLoad %uint %i
         %30 = OpAccessChain %_ptr_StorageBuffer_half %__0 %int_0 %28
         %31 = OpLoad %half %30
         %33 = OpFConvert %half %31
         %34 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0 %23
               OpStore %34 %33
               OpReturn
               OpFunctionEnd

Version

I also test the bug also exists on current master.

OS: ArchLinux

$ glslang --version
Glslang Version: 11:14.1.0
ESSL Version: OpenGL ES GLSL 3.20 glslang Khronos. 14.1.0
GLSL Version: 4.60 glslang Khronos. 14.1.0
SPIR-V Version 0x00010600, Revision 1
GLSL.std.450 Version 100, Revision 1
Khronos Tool ID 8
SPIR-V Generator Version 11
GL_KHR_vulkan_glsl version 100
ARB_GL_gl_spirv version 100
@FanShupei
Copy link
Author

Sorry I open the issue in wrong repo. I will open it at glslang repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant