#version 460
#extension GL_EXT_buffer_reference2 : require
#extension GL_EXT_buffer_reference_uvec2 : require
layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;

layout(buffer_reference) buffer PhysicalPointerFloat4Array;
layout(buffer_reference) buffer PhysicalPointerUint4NonWriteCBVArray;
layout(buffer_reference) buffer PhysicalPointerUintNonWriteArray;

layout(buffer_reference, buffer_reference_align = 16, std430) buffer PhysicalPointerFloat4Array
{
    vec4 value[];
};

layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer PhysicalPointerUint4NonWriteCBVArray
{
    uvec4 value[4096];
};

layout(buffer_reference, buffer_reference_align = 4, std430) readonly buffer PhysicalPointerUintNonWriteArray
{
    uint value[];
};

layout(set = 0, binding = 1, std430) restrict readonly buffer SSBO
{
    uvec4 _m0[];
} _14;

layout(set = 0, binding = 2, std430) writeonly buffer _16_18
{
    uvec4 _m0[];
} _18;

layout(push_constant, std430) uniform RootConstants
{
    uvec2 _m0;
    uvec2 _m1;
    uvec2 _m2;
    uvec2 _m3;
} registers;

void main()
{
    PhysicalPointerFloat4Array(registers._m2).value[gl_LocalInvocationIndex] = vec4(0.0);
    if (!(PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x == 0u))
    {
        uint _70 = 0u;
        uint _74;
        uint _81;
        bool _83;
        for (;;)
        {
            _74 = (_70 << 8u) + gl_LocalInvocationIndex;
            _81 = PhysicalPointerUintNonWriteArray(registers._m1).value[_74];
            groupMemoryBarrier();
            barrier();
            _83 = _81 < 256u;
            if (_83)
            {
                vec4 _87 = uintBitsToFloat(_14._m0[_74]);
                PhysicalPointerFloat4Array _92 = PhysicalPointerFloat4Array(registers._m2);
                PhysicalPointerFloat4Array(registers._m2).value[_81] = vec4(_92.value[_81].x + _87.x, _92.value[_81].y + _87.y, _92.value[_81].z + _87.z, _92.value[_81].w + _87.w);
            }
            uint _71 = _70 + 1u;
            if (_71 < PhysicalPointerUint4NonWriteCBVArray(registers._m0).value[0u].x)
            {
                _70 = _71;
                continue;
            }
            else
            {
                break;
            }
        }
    }
    PhysicalPointerFloat4Array _56 = PhysicalPointerFloat4Array(registers._m3);
    _18._m0[gl_LocalInvocationIndex] = uvec4(floatBitsToUint(_56.value[gl_LocalInvocationIndex].x), floatBitsToUint(_56.value[gl_LocalInvocationIndex].y), floatBitsToUint(_56.value[gl_LocalInvocationIndex].z), floatBitsToUint(_56.value[gl_LocalInvocationIndex].w));
}


#if 0
// SPIR-V disassembly
; SPIR-V
; Version: 1.6
; Generator: Unknown(30017); 21022
; Bound: 121
; Schema: 0
OpCapability Shader
OpCapability VulkanMemoryModel
OpCapability PhysicalStorageBufferAddresses
OpExtension "SPV_KHR_physical_storage_buffer"
OpMemoryModel PhysicalStorageBuffer64 Vulkan
OpEntryPoint GLCompute %3 "main" %9 %14 %18 %33
OpExecutionMode %3 LocalSize 256 1 1
OpName %3 "main"
OpName %7 "RootConstants"
OpName %9 "registers"
OpName %12 "SSBO"
OpName %16 "SSBO"
OpName %38 "PhysicalPointerFloat4Array"
OpMemberName %38 0 "value"
OpName %47 "PhysicalPointerUint4NonWriteCBVArray"
OpMemberName %47 0 "value"
OpName %76 "PhysicalPointerUintNonWriteArray"
OpMemberName %76 0 "value"
OpDecorate %7 Block
OpMemberDecorate %7 0 Offset 0
OpMemberDecorate %7 1 Offset 8
OpMemberDecorate %7 2 Offset 16
OpMemberDecorate %7 3 Offset 24
OpDecorate %11 ArrayStride 16
OpMemberDecorate %12 0 Offset 0
OpDecorate %12 Block
OpDecorate %14 DescriptorSet 0
OpDecorate %14 Binding 1
OpDecorate %14 NonWritable
OpDecorate %14 Restrict
OpDecorate %15 ArrayStride 16
OpMemberDecorate %16 0 Offset 0
OpDecorate %16 Block
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 2
OpDecorate %18 NonReadable
OpDecorate %33 BuiltIn LocalInvocationIndex
OpDecorate %37 ArrayStride 16
OpMemberDecorate %38 0 Offset 0
OpDecorate %38 Block
OpDecorate %46 ArrayStride 16
OpMemberDecorate %47 0 Offset 0
OpDecorate %47 Block
OpMemberDecorate %47 0 NonWritable
OpDecorate %75 ArrayStride 4
OpMemberDecorate %76 0 Offset 0
OpDecorate %76 Block
OpMemberDecorate %76 0 NonWritable
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%5 = OpTypeInt 32 0
%6 = OpTypeVector %5 2
%7 = OpTypeStruct %6 %6 %6 %6
%8 = OpTypePointer PushConstant %7
%9 = OpVariable %8 PushConstant
%10 = OpTypeVector %5 4
%11 = OpTypeRuntimeArray %10
%12 = OpTypeStruct %11
%13 = OpTypePointer StorageBuffer %12
%14 = OpVariable %13 StorageBuffer
%15 = OpTypeRuntimeArray %10
%16 = OpTypeStruct %15
%17 = OpTypePointer StorageBuffer %16
%18 = OpVariable %17 StorageBuffer
%19 = OpTypePointer PushConstant %6
%21 = OpConstant %5 3
%24 = OpConstant %5 2
%27 = OpConstant %5 1
%30 = OpConstant %5 0
%32 = OpTypePointer Input %5
%33 = OpVariable %32 Input
%35 = OpTypeFloat 32
%36 = OpTypeVector %35 4
%37 = OpTypeRuntimeArray %36
%38 = OpTypeStruct %37
%39 = OpTypePointer PhysicalStorageBuffer %38
%41 = OpTypePointer PhysicalStorageBuffer %36
%43 = OpConstant %35 0
%45 = OpConstant %5 4096
%46 = OpTypeArray %10 %45
%47 = OpTypeStruct %46
%48 = OpTypePointer PhysicalStorageBuffer %47
%50 = OpTypePointer PhysicalStorageBuffer %10
%54 = OpTypeBool
%68 = OpTypePointer StorageBuffer %10
%73 = OpConstant %5 8
%75 = OpTypeRuntimeArray %5
%76 = OpTypeStruct %75
%77 = OpTypePointer PhysicalStorageBuffer %76
%79 = OpTypePointer PhysicalStorageBuffer %5
%82 = OpConstant %5 26696
%84 = OpConstant %5 256
%3 = OpFunction %1 None %2
%4 = OpLabel
OpBranch %111
%111 = OpLabel
%20 = OpAccessChain %19 %9 %21
%22 = OpLoad %6 %20
%23 = OpAccessChain %19 %9 %24
%25 = OpLoad %6 %23
%26 = OpAccessChain %19 %9 %27
%28 = OpLoad %6 %26
%29 = OpAccessChain %19 %9 %30
%31 = OpLoad %6 %29
%34 = OpLoad %5 %33
%40 = OpBitcast %39 %25
%42 = OpInBoundsAccessChain %41 %40 %30 %34
%44 = OpCompositeConstruct %36 %43 %43 %43 %43
OpStore %42 %44 Aligned|NonPrivatePointer 16
%49 = OpBitcast %48 %31
%51 = OpInBoundsAccessChain %50 %49 %30 %30
%52 = OpLoad %10 %51 Aligned 16
%53 = OpCompositeExtract %5 %52 0
%55 = OpIEqual %54 %53 %30
OpSelectionMerge %119 None
OpBranchConditional %55 %119 %112
%112 = OpLabel
OpBranch %113
%113 = OpLabel
%70 = OpPhi %5 %30 %112 %71 %117
%72 = OpShiftLeftLogical %5 %70 %73
%74 = OpIAdd %5 %72 %34
%78 = OpBitcast %77 %28
%80 = OpInBoundsAccessChain %79 %78 %30 %74
%81 = OpLoad %5 %80 Aligned 4
OpControlBarrier %24 %24 %82
%83 = OpULessThan %54 %81 %84
OpLoopMerge %118 %117 None
OpBranch %114
%114 = OpLabel
OpSelectionMerge %116 None
OpBranchConditional %83 %115 %116
%115 = OpLabel
%85 = OpAccessChain %68 %14 %30 %74
%86 = OpLoad %10 %85
%87 = OpBitcast %36 %86
%88 = OpCompositeExtract %35 %87 0
%89 = OpCompositeExtract %35 %87 1
%90 = OpCompositeExtract %35 %87 2
%91 = OpCompositeExtract %35 %87 3
%92 = OpBitcast %39 %25
%93 = OpInBoundsAccessChain %41 %92 %30 %81
%94 = OpLoad %36 %93 Aligned|NonPrivatePointer 16
%95 = OpCompositeExtract %35 %94 0
%96 = OpCompositeExtract %35 %94 1
%97 = OpCompositeExtract %35 %94 2
%98 = OpCompositeExtract %35 %94 3
%99 = OpFAdd %35 %95 %88
%100 = OpFAdd %35 %96 %89
%101 = OpFAdd %35 %97 %90
%102 = OpFAdd %35 %98 %91
%103 = OpBitcast %39 %25
%104 = OpInBoundsAccessChain %41 %103 %30 %81
%105 = OpCompositeConstruct %36 %99 %100 %101 %102
OpStore %104 %105 Aligned|NonPrivatePointer 16
OpBranch %116
%116 = OpLabel
OpBranch %117
%117 = OpLabel
%71 = OpIAdd %5 %70 %27
%106 = OpBitcast %48 %31
%107 = OpInBoundsAccessChain %50 %106 %30 %30
%108 = OpLoad %10 %107 Aligned 16
%109 = OpCompositeExtract %5 %108 0
%110 = OpULessThan %54 %71 %109
OpBranchConditional %110 %113 %118
%118 = OpLabel
OpBranch %119
%119 = OpLabel
%56 = OpBitcast %39 %22
%57 = OpInBoundsAccessChain %41 %56 %30 %34
%58 = OpLoad %36 %57 Aligned|NonPrivatePointer 16
%59 = OpCompositeExtract %35 %58 0
%60 = OpCompositeExtract %35 %58 1
%61 = OpCompositeExtract %35 %58 2
%62 = OpCompositeExtract %35 %58 3
%63 = OpBitcast %5 %59
%64 = OpBitcast %5 %60
%65 = OpBitcast %5 %61
%66 = OpBitcast %5 %62
%67 = OpCompositeConstruct %10 %63 %64 %65 %66
%69 = OpAccessChain %68 %18 %30 %34
OpStore %69 %67 NonPrivatePointer
OpReturn
OpFunctionEnd
#endif
