#include <metal_stdlib>

using namespace metal;

struct atomic_compare_exchange_result_u32 {
  uint old_value;
  bool exchanged;
};
atomic_compare_exchange_result_u32 atomicCompareExchangeWeak_1(device atomic_uint* atomic, uint compare, uint value) {
  uint old_value = compare;
  bool exchanged = atomic_compare_exchange_weak_explicit(atomic, &old_value, value, memory_order_relaxed, memory_order_relaxed);
  return {old_value, exchanged};
}

struct SB_RW_atomic {
  /* 0x0000 */ atomic_uint arg_0;
};

struct SB_RW {
  uint arg_0;
};

struct x__atomic_compare_exchange_resultu32 {
  uint old_value;
  bool exchanged;
};

void atomicCompareExchangeWeak_63d8e6(device SB_RW_atomic* const tint_symbol_2) {
  uint arg_1 = 0u;
  uint arg_2 = 0u;
  x__atomic_compare_exchange_resultu32 res = x__atomic_compare_exchange_resultu32{};
  arg_1 = 1u;
  arg_2 = 1u;
  uint const x_21 = arg_2;
  uint const x_22 = arg_1;
  atomic_compare_exchange_result_u32 const tint_symbol = atomicCompareExchangeWeak_1(&((*(tint_symbol_2)).arg_0), x_22, x_21);
  uint const old_value_1 = tint_symbol.old_value;
  uint const x_23 = old_value_1;
  x__atomic_compare_exchange_resultu32 const tint_symbol_1 = {.old_value=x_23, .exchanged=(x_23 == x_21)};
  res = tint_symbol_1;
  return;
}

void fragment_main_1(device SB_RW_atomic* const tint_symbol_3) {
  atomicCompareExchangeWeak_63d8e6(tint_symbol_3);
  return;
}

fragment void fragment_main(device SB_RW_atomic* tint_symbol_4 [[buffer(0)]]) {
  fragment_main_1(tint_symbol_4);
  return;
}

void compute_main_1(device SB_RW_atomic* const tint_symbol_5) {
  atomicCompareExchangeWeak_63d8e6(tint_symbol_5);
  return;
}

kernel void compute_main(device SB_RW_atomic* tint_symbol_6 [[buffer(0)]]) {
  compute_main_1(tint_symbol_6);
  return;
}

