Skip to content

[SPIR-V] Float16 capability getting emitted even if no Half arithmetic present #7950

@devshgraphicsprogramming

Description

Description

I'd expect if I only use 16bit storage and immediately OpFConvert to 32bit floats, I would not get the Vulkan shaderFloat16 a.k.a. Float16 SPIR-V capability emitted.

To quote the spec:

The capabilities StorageBuffer16BitAccess, UniformAndStorageBuffer16BitAccess, StoragePushConstant16, and StorageInputOutput16 do not generally add 16-bit operations. Rather, they add only the following specific abilities:

An OpTypePointer pointing to a 16-bit scalar, a 16-bit vector, or a composite containing a 16-bit member can be used as the result type of OpVariable, or OpAccessChain, or OpInBoundsAccessChain.

OpLoad can load 16-bit scalars, 16-bit vectors, and 16-bit matrices.

OpStore can store 16-bit scalars, 16-bit vectors, and 16-bit matrices.

OpCopyObject can be used for 16-bit scalars or composites containing 16-bit members.

16-bit scalars or 16-bit vectors can be used as operands to a width-only conversion instruction to another allowed type (OpFConvert, OpSConvert, or OpUConvert), and can be produced as results of a width-only conversion instruction from another allowed type.

A structure containing a 16-bit member can be an operand to OpArrayLength.

For context, I'm also not sure that StoragePushConstant16 should be emitted but bringing that up with the SPIR-V folks for now:
KhronosGroup/SPIRV-Tools#6435

Steps to Reproduce

struct PushConstants
{
    float16_t2 pairOfHalves;
};

[[vk::push_constant]] PushConstants pc;


[numthreads(1,1,1)]
[shader("compute")]
void main()
{
    float32_t2 promoted = pc.pairOfHalves;
    vk::RawBufferStore(0xdeadbeefull, promoted);
}

https://godbolt.org/z/8x8vEYndW

Actual Behavior

produces

               OpCapability Shader
               OpCapability Int64
               OpCapability StoragePushConstant16
               OpCapability Float16
               OpCapability PhysicalStorageBufferAddresses
               OpMemoryModel PhysicalStorageBuffer64 GLSL450
               OpEntryPoint GLCompute %main "main" %pc
               OpExecutionMode %main LocalSize 1 1 1
               OpMemberDecorate %type_PushConstant_PushConstants 0 Offset 0
               OpDecorate %type_PushConstant_PushConstants Block
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
      %ulong = OpTypeInt 64 0
%ulong_3735928559 = OpConstant %ulong 3735928559
       %half = OpTypeFloat 16
     %v2half = OpTypeVector %half 2
%type_PushConstant_PushConstants = OpTypeStruct %v2half
%_ptr_PushConstant_type_PushConstant_PushConstants = OpTypePointer PushConstant %type_PushConstant_PushConstants
       %void = OpTypeVoid
         %12 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v2float = OpTypeVector %float 2
%_ptr_PushConstant_v2half = OpTypePointer PushConstant %v2half
%_ptr_PhysicalStorageBuffer_v2float = OpTypePointer PhysicalStorageBuffer %v2float
         %pc = OpVariable %_ptr_PushConstant_type_PushConstant_PushConstants PushConstant
       %main = OpFunction %void None %12
         %17 = OpLabel
         %18 = OpAccessChain %_ptr_PushConstant_v2half %pc %int_0
         %19 = OpLoad %v2half %18
         %20 = OpFConvert %v2float %19
         %21 = OpBitcast %_ptr_PhysicalStorageBuffer_v2float %ulong_3735928559
               OpStore %21 %20 Aligned 4
               OpReturn
               OpFunctionEnd

Environment

  • DXC version
  • Host Operating System <!--- Host operating system and version --->

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug, regression, crashneeds-triageAwaiting triagespirvWork related to SPIR-V

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions