#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device int4* prevent_dce;
};

struct VertexOutput {
  float4 pos;
  int4 prevent_dce;
};

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

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

fragment void fragment_main(device int4* 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_86551b();
}

kernel void compute_main(device int4* 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_86551b();
}

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