#version 460
#if defined(GL_ARB_gpu_shader_int64)
#extension GL_ARB_gpu_shader_int64 : require
#else
#error No extension available for 64-bit integers.
#endif
layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;

struct CmpXchgResult
{
    uint64_t _m0;
    bool _m1;
};

layout(set = 0, binding = 0, std430) writeonly buffer SSBO
{
    uint64_t _m0[];
} _9;

shared uint64_t _14[4];

void main()
{
    bool _23 = gl_GlobalInvocationID.x < 4u;
    if (_23)
    {
        _14[gl_GlobalInvocationID.x] = 0ul;
    }
    barrier();
    uint _29 = gl_GlobalInvocationID.x & 3u;
    uint64_t _31 = uint64_t(gl_GlobalInvocationID.x);
    uint64_t _33 = atomicAdd(_14[_29], _31);
    uint64_t _34 = atomicAnd(_14[_29], _31);
    uint64_t _35 = atomicOr(_14[_29], _31);
    uint64_t _36 = atomicXor(_14[_29], _31);
    uint64_t _37 = atomicMin(_14[_29], _31);
    uint64_t _38 = atomicMax(_14[_29], _31);
    uint64_t _39 = atomicMin(_14[_29], _31);
    uint64_t _40 = atomicMax(_14[_29], _31);
    uint64_t _41 = atomicExchange(_14[_29], _31);
    uint64_t _42 = atomicCompSwap(_14[_29], 10ul, _41);
    uint64_t _47 = atomicCompSwap(_14[_29], 20ul, _31);
    uint64_t _51 = atomicAdd(_14[_29], _31);
    uint64_t _52 = atomicAdd(_14[_29], _31);
    barrier();
    if (_23)
    {
        _9._m0[gl_GlobalInvocationID.x] = _14[gl_GlobalInvocationID.x];
    }
}


#if 0
// SPIR-V disassembly
; SPIR-V
; Version: 1.3
; Generator: Unknown(30017); 21022
; Bound: 64
; Schema: 0
OpCapability Shader
OpCapability Int64
OpCapability Int64Atomics
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %3 "main" %17
OpExecutionMode %3 LocalSize 128 1 1
OpName %3 "main"
OpName %7 "SSBO"
OpName %45 "CmpXchgResult"
OpDecorate %6 ArrayStride 8
OpMemberDecorate %7 0 Offset 0
OpDecorate %7 Block
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
OpDecorate %9 NonReadable
OpDecorate %17 BuiltIn GlobalInvocationId
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%5 = OpTypeInt 64 0
%6 = OpTypeRuntimeArray %5
%7 = OpTypeStruct %6
%8 = OpTypePointer StorageBuffer %7
%9 = OpVariable %8 StorageBuffer
%10 = OpTypeInt 32 0
%11 = OpConstant %10 4
%12 = OpTypeArray %5 %11
%13 = OpTypePointer Workgroup %12
%14 = OpVariable %13 Workgroup
%15 = OpTypeVector %10 3
%16 = OpTypePointer Input %15
%17 = OpVariable %16 Input
%18 = OpTypePointer Input %10
%20 = OpConstant %10 0
%22 = OpTypeBool
%24 = OpTypePointer Workgroup %5
%26 = OpConstant %5 0
%27 = OpConstant %10 2
%28 = OpConstant %10 264
%30 = OpConstant %10 3
%43 = OpConstant %5 10
%45 = OpTypeStruct %5 %22
%48 = OpConstant %5 20
%56 = OpTypePointer StorageBuffer %5
%3 = OpFunction %1 None %2
%4 = OpLabel
OpBranch %58
%58 = OpLabel
%19 = OpAccessChain %18 %17 %20
%21 = OpLoad %10 %19
%23 = OpULessThan %22 %21 %11
OpSelectionMerge %60 None
OpBranchConditional %23 %59 %60
%59 = OpLabel
%25 = OpAccessChain %24 %14 %21
OpStore %25 %26
OpBranch %60
%60 = OpLabel
OpControlBarrier %27 %27 %28
%29 = OpBitwiseAnd %10 %21 %30
%31 = OpUConvert %5 %21
%32 = OpAccessChain %24 %14 %29
%33 = OpAtomicIAdd %5 %32 %27 %20 %31
%34 = OpAtomicAnd %5 %32 %27 %20 %31
%35 = OpAtomicOr %5 %32 %27 %20 %31
%36 = OpAtomicXor %5 %32 %27 %20 %31
%37 = OpAtomicSMin %5 %32 %27 %20 %31
%38 = OpAtomicSMax %5 %32 %27 %20 %31
%39 = OpAtomicSMin %5 %32 %27 %20 %31
%40 = OpAtomicSMax %5 %32 %27 %20 %31
%41 = OpAtomicExchange %5 %32 %27 %20 %31
%42 = OpAtomicCompareExchange %5 %32 %27 %20 %20 %41 %43
%44 = OpIEqual %22 %42 %43
%46 = OpCompositeConstruct %45 %42 %44
%47 = OpAtomicCompareExchange %5 %32 %27 %20 %20 %31 %48
%49 = OpIEqual %22 %47 %48
%50 = OpCompositeConstruct %45 %47 %49
%51 = OpAtomicIAdd %5 %32 %27 %20 %31
%52 = OpAtomicIAdd %5 %32 %27 %20 %31
OpControlBarrier %27 %27 %28
OpSelectionMerge %62 None
OpBranchConditional %23 %61 %62
%61 = OpLabel
%53 = OpAccessChain %24 %14 %21
%54 = OpLoad %5 %53
%55 = OpShiftLeftLogical %10 %21 %30
%57 = OpAccessChain %56 %9 %20 %21
OpStore %57 %54
OpBranch %62
%62 = OpLabel
OpReturn
OpFunctionEnd
#endif
