void rgb_to_hsv(unsigned short r, unsigned short g, unsigned short b, int *h,
                float *s, float *v) {
  float R, G, B, H, S, V;
  float cmax, cmin;
  float cmm;
  int imax;
  R = ((float)r) / 65535.0;
  G = ((float)g) / 65535.0;
  B = ((float)b) / 65535.0;
  cmax = R;
  cmin = G;
  imax = 1;
  if (cmax < G) {
    cmax = G;
    cmin = R;
    imax = 2;
  }
  if (cmax < B) {
    cmax = B;
    imax = 3;
  }
  if (cmin > B) {
    cmin = B;
  }
  cmm = cmax - cmin;
  V = cmax;
  if (cmm == 0)
    S = H = 0;
  else {
    S = cmm / cmax;
    if (imax == 1)
      H = (G - B) / cmm;
    else if (imax == 2)
      H = 2.0 + (B - R) / cmm;
    else
      H = 4.0 + (R - G) / cmm;
    if (H < 0)
      H += 6.0;
  }
  *h = (H * 60.0);
  *s = S;
  *v = V;
}


x86 assembly (clang, -O0):
<rgb_to_hsv>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %si,%dx
mov    %di,%si
mov    %si,-0x2(%rbp)
mov    %dx,-0x4(%rbp)
mov    %ax,-0x6(%rbp)
mov    %rcx,-0x10(%rbp)
mov    %r8,-0x18(%rbp)
mov    %r9,-0x20(%rbp)
movzwl -0x2(%rbp),%eax
cvtsi2ss %eax,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xec7(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
movzwl -0x4(%rbp),%eax
cvtsi2ss %eax,%xmm0
cvtss2sd %xmm0,%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
movzwl -0x6(%rbp),%eax
cvtsi2ss %eax,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe8d(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
movl   $0x1,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm1
movss  -0x28(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    11c9 <rgb_to_hsv+0xc9>
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
movl   $0x2,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm1
movss  -0x2c(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    11ed <rgb_to_hsv+0xed>
movss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movl   $0x3,-0x48(%rbp)
movss  -0x40(%rbp),%xmm0
ucomiss -0x2c(%rbp),%xmm0
jbe    1206 <rgb_to_hsv+0x106>
movss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
movss  -0x3c(%rbp),%xmm0
subss  -0x40(%rbp),%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x44(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    124b <rgb_to_hsv+0x14b>
jp     124b <rgb_to_hsv+0x14b>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x34(%rbp)
jmp    1311 <rgb_to_hsv+0x211>
movss  -0x44(%rbp),%xmm0
divss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
cmpl   $0x1,-0x48(%rbp)
jne    127d <rgb_to_hsv+0x17d>
movss  -0x28(%rbp),%xmm0
subss  -0x2c(%rbp),%xmm0
divss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    12e1 <rgb_to_hsv+0x1e1>
cmpl   $0x2,-0x48(%rbp)
jne    12b4 <rgb_to_hsv+0x1b4>
movss  -0x2c(%rbp),%xmm0
subss  -0x24(%rbp),%xmm0
divss  -0x44(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd6e(%rip),%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    12dc <rgb_to_hsv+0x1dc>
movss  -0x24(%rbp),%xmm0
subss  -0x28(%rbp),%xmm0
divss  -0x44(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd39(%rip),%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    12e1 <rgb_to_hsv+0x1e1>
xorps  %xmm0,%xmm0
ucomiss -0x30(%rbp),%xmm0
jbe    130c <rgb_to_hsv+0x20c>
movss  -0x30(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd19(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    1311 <rgb_to_hsv+0x211>
movss  -0x30(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xcfe(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movss  -0x34(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x38(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<rgb_to_hsv>:
movd   %edi,%xmm0
pinsrw $0x2,%esi,%xmm0
cvtdq2pd %xmm0,%xmm0
divpd  0xeeb(%rip),%xmm0
cvtpd2ps %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %edx,%xmm0
divsd  0xee8(%rip),%xmm0
cvtsd2ss %xmm0,%xmm3
movapd %xmm2,%xmm4
shufps $0x55,%xmm2,%xmm4
movaps %xmm4,%xmm6
maxss  %xmm2,%xmm6
movaps %xmm2,%xmm1
minss  %xmm4,%xmm1
movaps %xmm3,%xmm0
maxss  %xmm6,%xmm0
movaps %xmm3,%xmm5
minss  %xmm1,%xmm5
movaps %xmm0,%xmm1
subss  %xmm5,%xmm1
xorps  %xmm7,%xmm7
ucomiss %xmm7,%xmm1
xorps  %xmm5,%xmm5
jne    1164 <rgb_to_hsv+0x64>
jnp    11d0 <rgb_to_hsv+0xd0>
xor    %edx,%edx
ucomiss %xmm2,%xmm4
seta   %dl
add    $0x1,%edx
ucomiss %xmm6,%xmm3
mov    $0x3,%eax
cmovbe %edx,%eax
cmp    $0x2,%eax
je     1191 <rgb_to_hsv+0x91>
cmp    $0x1,%eax
jne    11a6 <rgb_to_hsv+0xa6>
subss  %xmm3,%xmm4
divss  %xmm1,%xmm4
movaps %xmm4,%xmm5
jmp    11b9 <rgb_to_hsv+0xb9>
subss  %xmm2,%xmm3
divss  %xmm1,%xmm3
addss  0xe7f(%rip),%xmm3
movaps %xmm3,%xmm5
jmp    11b9 <rgb_to_hsv+0xb9>
subss  %xmm4,%xmm2
divss  %xmm1,%xmm2
addss  0xe6e(%rip),%xmm2
movaps %xmm2,%xmm5
divss  %xmm0,%xmm1
xorps  %xmm2,%xmm2
ucomiss %xmm5,%xmm2
jbe    11cd <rgb_to_hsv+0xcd>
addss  0xe5b(%rip),%xmm5
movaps %xmm1,%xmm7
xorps  %xmm1,%xmm1
cvtss2sd %xmm5,%xmm1
mulsd  0xe39(%rip),%xmm1
cvttsd2si %xmm1,%eax
mov    %eax,(%rcx)
movss  %xmm7,(%r8)
movss  %xmm0,(%r9)
ret

LLVM IR (-O0):
define void @rgb_to_hsv(i16 zeroext %0, i16 zeroext %1, i16 zeroext %2, i32* %3, float* %4, float* %5) {
%7 = alloca i16
%8 = alloca i16
%9 = alloca i16
%10 = alloca i32*
%11 = alloca float*
%12 = alloca float*
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
%17 = alloca float
%18 = alloca float
%19 = alloca float
%20 = alloca float
%21 = alloca float
%22 = alloca i32
store i16 %0, i16* %7
store i16 %1, i16* %8
store i16 %2, i16* %9
store i32* %3, i32** %10
store float* %4, float** %11
store float* %5, float** %12
%23 = load i16, i16* %7
%24 = uitofp i16 %23 to float
%25 = fpext float %24 to double
%26 = fdiv double %25, 6.553500e+04
%27 = fptrunc double %26 to float
store float %27, float* %13
%28 = load i16, i16* %8
%29 = uitofp i16 %28 to float
%30 = fpext float %29 to double
%31 = fdiv double %30, 6.553500e+04
%32 = fptrunc double %31 to float
store float %32, float* %14
%33 = load i16, i16* %9
%34 = uitofp i16 %33 to float
%35 = fpext float %34 to double
%36 = fdiv double %35, 6.553500e+04
%37 = fptrunc double %36 to float
store float %37, float* %15
%38 = load float, float* %13
store float %38, float* %19
%39 = load float, float* %14
store float %39, float* %20
store i32 1, i32* %22
%40 = load float, float* %19
%41 = load float, float* %14
%42 = fcmp olt float %40, %41
br i1 %42, label %43, label %46
43: ; preds = %6
%44 = load float, float* %14
store float %44, float* %19
%45 = load float, float* %13
store float %45, float* %20
store i32 2, i32* %22
br label %46
46: ; preds = %43, %6
%47 = load float, float* %19
%48 = load float, float* %15
%49 = fcmp olt float %47, %48
br i1 %49, label %50, label %52
50: ; preds = %46
%51 = load float, float* %15
store float %51, float* %19
store i32 3, i32* %22
br label %52
52: ; preds = %50, %46
%53 = load float, float* %20
%54 = load float, float* %15
%55 = fcmp ogt float %53, %54
br i1 %55, label %56, label %58
56: ; preds = %52
%57 = load float, float* %15
store float %57, float* %20
br label %58
58: ; preds = %56, %52
%59 = load float, float* %19
%60 = load float, float* %20
%61 = fsub float %59, %60
store float %61, float* %21
%62 = load float, float* %19
store float %62, float* %18
%63 = load float, float* %21
%64 = fcmp oeq float %63, 0.000000e+00
br i1 %64, label %65, label %66
65: ; preds = %58
store float 0.000000e+00, float* %16
store float 0.000000e+00, float* %17
br label %109
66: ; preds = %58
%67 = load float, float* %21
%68 = load float, float* %19
%69 = fdiv float %67, %68
store float %69, float* %17
%70 = load i32, i32* %22
%71 = icmp eq i32 %70, 1
br i1 %71, label %72, label %78
72: ; preds = %66
%73 = load float, float* %14
%74 = load float, float* %15
%75 = fsub float %73, %74
%76 = load float, float* %21
%77 = fdiv float %75, %76
store float %77, float* %16
br label %100
78: ; preds = %66
%79 = load i32, i32* %22
%80 = icmp eq i32 %79, 2
br i1 %80, label %81, label %90
81: ; preds = %78
%82 = load float, float* %15
%83 = load float, float* %13
%84 = fsub float %82, %83
%85 = load float, float* %21
%86 = fdiv float %84, %85
%87 = fpext float %86 to double
%88 = fadd double 2.000000e+00, %87
%89 = fptrunc double %88 to float
store float %89, float* %16
br label %99
90: ; preds = %78
%91 = load float, float* %13
%92 = load float, float* %14
%93 = fsub float %91, %92
%94 = load float, float* %21
%95 = fdiv float %93, %94
%96 = fpext float %95 to double
%97 = fadd double 4.000000e+00, %96
%98 = fptrunc double %97 to float
store float %98, float* %16
br label %99
99: ; preds = %90, %81
br label %100
100: ; preds = %99, %72
%101 = load float, float* %16
%102 = fcmp olt float %101, 0.000000e+00
br i1 %102, label %103, label %108
103: ; preds = %100
%104 = load float, float* %16
%105 = fpext float %104 to double
%106 = fadd double %105, 6.000000e+00
%107 = fptrunc double %106 to float
store float %107, float* %16
br label %108
108: ; preds = %103, %100
br label %109
109: ; preds = %108, %65
%110 = load float, float* %16
%111 = fpext float %110 to double
%112 = fmul double %111, 6.000000e+01
%113 = fptosi double %112 to i32
%114 = load i32*, i32** %10
store i32 %113, i32* %114
%115 = load float, float* %17
%116 = load float*, float** %11
store float %115, float* %116
%117 = load float, float* %18
%118 = load float*, float** %12
store float %117, float* %118
ret void
}

LLVM IR (-O2):
define void @rgb_to_hsv(i16 zeroext %0, i16 zeroext %1, i16 zeroext %2, i32* nocapture writeonly %3, float* nocapture writeonly %4, float* nocapture writeonly %5) {
%7 = insertelement <2 x i16> poison, i16 %0, i64 0
%8 = insertelement <2 x i16> %7, i16 %1, i64 1
%9 = uitofp <2 x i16> %8 to <2 x double>
%10 = fdiv <2 x double> %9, <double 6.553500e+04, double 6.553500e+04>
%11 = fptrunc <2 x double> %10 to <2 x float>
%12 = uitofp i16 %2 to double
%13 = fdiv double %12, 6.553500e+04
%14 = fptrunc double %13 to float
%15 = extractelement <2 x float> %11, i64 0
%16 = extractelement <2 x float> %11, i64 1
%17 = fcmp olt float %15, %16
%18 = select i1 %17, float %16, float %15
%19 = select i1 %17, float %15, float %16
%20 = fcmp olt float %18, %14
%21 = select i1 %20, float %14, float %18
%22 = fcmp ogt float %19, %14
%23 = select i1 %22, float %14, float %19
%24 = fsub float %21, %23
%25 = fcmp oeq float %24, 0.000000e+00
br i1 %25, label %46, label %26
26: ; preds = %6
%27 = select i1 %17, i32 2, i32 1
%28 = select i1 %20, i32 3, i32 %27
%29 = fdiv float %24, %21
switch i32 %28, label %37 [
i32 1, label %30
i32 2, label %33
]
30: ; preds = %26
%31 = fsub float %16, %14
%32 = fdiv float %31, %24
br label %41
33: ; preds = %26
%34 = fsub float %14, %15
%35 = fdiv float %34, %24
%36 = fadd float %35, 2.000000e+00
br label %41
37: ; preds = %26
%38 = fsub float %15, %16
%39 = fdiv float %38, %24
%40 = fadd float %39, 4.000000e+00
br label %41
41: ; preds = %33, %37, %30
%42 = phi float [ %32, %30 ], [ %36, %33 ], [ %40, %37 ]
%43 = fcmp olt float %42, 0.000000e+00
br i1 %43, label %44, label %46
44: ; preds = %41
%45 = fadd float %42, 6.000000e+00
br label %46
46: ; preds = %6, %41, %44
%47 = phi float [ %29, %44 ], [ %29, %41 ], [ 0.000000e+00, %6 ]
%48 = phi float [ %45, %44 ], [ %42, %41 ], [ 0.000000e+00, %6 ]
%49 = fpext float %48 to double
%50 = fmul double %49, 6.000000e+01
%51 = fptosi double %50 to i32
store i32 %51, i32* %3
store float %47, float* %4
store float %21, float* %5
ret void
}