#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device int2* prevent_dce;
};

struct VertexOutput {
  float4 pos;
  int2 prevent_dce;
};

struct vertex_main_outputs {
  float4 VertexOutput_pos [[position]];
  int2 VertexOutput_prevent_dce [[user(locn0)]] [[flat]];
};

int2 firstTrailingBit_50c072() {
  int2 arg_0 = int2(1);
  uint2 const v = as_type<uint2>(arg_0);
  uint2 const v_1 = select(uint2(0u), uint2(16u), ((v & uint2(65535u)) == uint2(0u)));
  uint2 const v_2 = select(uint2(0u), uint2(8u), (((v >> v_1) & uint2(255u)) == uint2(0u)));
  uint2 const v_3 = select(uint2(0u), uint2(4u), ((((v >> v_1) >> v_2) & uint2(15u)) == uint2(0u)));
  uint2 const v_4 = select(uint2(0u), uint2(2u), (((((v >> v_1) >> v_2) >> v_3) & uint2(3u)) == uint2(0u)));
  int2 res = as_type<int2>(select((v_1 | (v_2 | (v_3 | (v_4 | select(uint2(0u), uint2(1u), ((((((v >> v_1) >> v_2) >> v_3) >> v_4) & uint2(1u)) == uint2(0u))))))), uint2(4294967295u), (((((v >> v_1) >> v_2) >> v_3) >> v_4) == uint2(0u))));
  return res;
}

fragment void fragment_main(device int2* prevent_dce [[buffer(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce};
  (*tint_module_vars.prevent_dce) = firstTrailingBit_50c072();
}

kernel void compute_main(device int2* prevent_dce [[buffer(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce};
  (*tint_module_vars.prevent_dce) = firstTrailingBit_50c072();
}

VertexOutput vertex_main_inner() {
  VertexOutput out = {};
  out.pos = float4(0.0f);
  out.prevent_dce = firstTrailingBit_50c072();
  return out;
}

vertex vertex_main_outputs vertex_main() {
  VertexOutput const v_5 = vertex_main_inner();
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.VertexOutput_pos = v_5.pos;
  tint_wrapper_result.VertexOutput_prevent_dce = v_5.prevent_dce;
  return tint_wrapper_result;
}
