#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device uint4* prevent_dce;
};

struct VertexOutput {
  float4 pos;
  uint4 prevent_dce;
};

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

uint4 firstLeadingBit_000ff3() {
  uint4 arg_0 = uint4(1u);
  uint4 const v = arg_0;
  uint4 const v_1 = select(uint4(16u), uint4(0u), ((v & uint4(4294901760u)) == uint4(0u)));
  uint4 const v_2 = select(uint4(8u), uint4(0u), (((v >> v_1) & uint4(65280u)) == uint4(0u)));
  uint4 const v_3 = select(uint4(4u), uint4(0u), ((((v >> v_1) >> v_2) & uint4(240u)) == uint4(0u)));
  uint4 const v_4 = select(uint4(2u), uint4(0u), (((((v >> v_1) >> v_2) >> v_3) & uint4(12u)) == uint4(0u)));
  uint4 res = select((v_1 | (v_2 | (v_3 | (v_4 | select(uint4(1u), uint4(0u), ((((((v >> v_1) >> v_2) >> v_3) >> v_4) & uint4(2u)) == uint4(0u))))))), uint4(4294967295u), (((((v >> v_1) >> v_2) >> v_3) >> v_4) == uint4(0u)));
  return res;
}

fragment void fragment_main(device uint4* 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) = firstLeadingBit_000ff3();
}

kernel void compute_main(device uint4* 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) = firstLeadingBit_000ff3();
}

VertexOutput vertex_main_inner() {
  VertexOutput out = {};
  out.pos = float4(0.0f);
  out.prevent_dce = firstLeadingBit_000ff3();
  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;
}
