void hsv_to_rgb(int h, float s, float v, unsigned short *r, unsigned short *g,
                unsigned short *b) {
  float H, S, V, R, G, B;
  float p1, p2, p3;
  float f;
  int i;
  if (s < 0)
    s = 0;
  if (v < 0)
    v = 0;
  if (s > 1)
    s = 1;
  if (v > 1)
    v = 1;
  S = s;
  V = v;
  H = (h % 360) / 60.0;
  i = H;
  f = H - i;
  p1 = V * (1 - S);
  p2 = V * (1 - (S * f));
  p3 = V * (1 - (S * (1 - f)));
  if (i == 0) {
    R = V;
    G = p3;
    B = p1;
  } else if (i == 1) {
    R = p2;
    G = V;
    B = p1;
  } else if (i == 2) {
    R = p1;
    G = V;
    B = p3;
  } else if (i == 3) {
    R = p1;
    G = p2;
    B = V;
  } else if (i == 4) {
    R = p3;
    G = p1;
    B = V;
  } else {
    R = V;
    G = p1;
    B = p2;
  }
  *r = R * 65535;
  *g = G * 65535;
  *b = B * 65535;
}


x86 assembly (clang, -O0):
<hsv_to_rgb>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x8(%rbp),%xmm0
jbe    1132 <hsv_to_rgb+0x32>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x8(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0xc(%rbp),%xmm0
jbe    1147 <hsv_to_rgb+0x47>
xorps  %xmm0,%xmm0
movss  %xmm0,-0xc(%rbp)
movss  -0x8(%rbp),%xmm0
movss  0xeac(%rip),%xmm1
ucomiss %xmm1,%xmm0
jbe    116a <hsv_to_rgb+0x6a>
movss  0xe9b(%rip),%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0xc(%rbp),%xmm0
movss  0xe89(%rip),%xmm1
ucomiss %xmm1,%xmm0
jbe    118d <hsv_to_rgb+0x8d>
movss  0xe78(%rip),%xmm0
movss  %xmm0,-0xc(%rbp)
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0xc(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x168,%ecx
cltd
idiv   %ecx
cvtsi2sd %edx,%xmm0
movsd  0xe50(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
cvttss2si -0x2c(%rbp),%eax
mov    %eax,-0x54(%rbp)
movss  -0x2c(%rbp),%xmm0
cvtsi2ssl -0x54(%rbp),%xmm1
subss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x34(%rbp),%xmm0
movss  0xe13(%rip),%xmm1
subss  -0x30(%rbp),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x34(%rbp),%xmm0
movss  -0x30(%rbp),%xmm1
movss  -0x50(%rbp),%xmm2
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm1
movss  0xddd(%rip),%xmm2
addss  %xmm2,%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x34(%rbp),%xmm0
movss  -0x30(%rbp),%xmm1
movss  0xdbe(%rip),%xmm2
subss  -0x50(%rbp),%xmm2
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm1
movss  0xda0(%rip),%xmm2
addss  %xmm2,%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
cmpl   $0x0,-0x54(%rbp)
jne    129a <hsv_to_rgb+0x19a>
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x4c(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    1380 <hsv_to_rgb+0x280>
cmpl   $0x1,-0x54(%rbp)
jne    12c7 <hsv_to_rgb+0x1c7>
movss  -0x48(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    137b <hsv_to_rgb+0x27b>
cmpl   $0x2,-0x54(%rbp)
jne    12f4 <hsv_to_rgb+0x1f4>
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x4c(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    1376 <hsv_to_rgb+0x276>
cmpl   $0x3,-0x54(%rbp)
jne    1321 <hsv_to_rgb+0x221>
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x48(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    1371 <hsv_to_rgb+0x271>
cmpl   $0x4,-0x54(%rbp)
jne    134e <hsv_to_rgb+0x24e>
movss  -0x4c(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    136c <hsv_to_rgb+0x26c>
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x48(%rbp),%xmm0
movss  %xmm0,-0x40(%rbp)
jmp    1371 <hsv_to_rgb+0x271>
jmp    1376 <hsv_to_rgb+0x276>
jmp    137b <hsv_to_rgb+0x27b>
jmp    1380 <hsv_to_rgb+0x280>
movss  -0x38(%rbp),%xmm0
movss  0xc77(%rip),%xmm1
mulss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %ax,%cx
mov    -0x18(%rbp),%rax
mov    %cx,(%rax)
movss  -0x3c(%rbp),%xmm0
mulss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %ax,%cx
mov    -0x20(%rbp),%rax
mov    %cx,(%rax)
movss  -0x40(%rbp),%xmm0
mulss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<hsv_to_rgb>:
xorps  %xmm3,%xmm3
xorps  %xmm4,%xmm4
maxss  %xmm0,%xmm4
maxss  %xmm1,%xmm3
movss  0xeea(%rip),%xmm1
movaps %xmm1,%xmm2
minss  %xmm4,%xmm2
movaps %xmm1,%xmm0
movslq %edi,%rax
imul   $0xffffffffb60b60b7,%rax,%rdi
shr    $0x20,%rdi
add    %eax,%edi
mov    %edi,%r8d
shr    $0x1f,%r8d
sar    $0x8,%edi
add    %r8d,%edi
imul   $0x168,%edi,%edi
sub    %edi,%eax
xorps  %xmm4,%xmm4
cvtsi2sd %eax,%xmm4
divsd  0xeb4(%rip),%xmm4
cvtsd2ss %xmm4,%xmm5
minss  %xmm3,%xmm0
cvttss2si %xmm5,%eax
cvttps2dq %xmm5,%xmm3
cvtdq2ps %xmm3,%xmm3
subss  %xmm3,%xmm5
movaps %xmm1,%xmm3
subss  %xmm2,%xmm3
mulss  %xmm0,%xmm3
movaps %xmm2,%xmm6
mulss  %xmm5,%xmm6
movaps %xmm1,%xmm4
subss  %xmm6,%xmm4
mulss  %xmm0,%xmm4
cmp    $0x4,%eax
ja     11c1 <hsv_to_rgb+0xc1>
movaps %xmm1,%xmm6
subss  %xmm5,%xmm6
mulss  %xmm6,%xmm2
subss  %xmm2,%xmm1
mulss  %xmm0,%xmm1
lea    0xe69(%rip),%rdi
movslq (%rdi,%rax,4),%rax
add    %rdi,%rax
movaps %xmm3,%xmm2
movaps %xmm1,%xmm5
jmp    *%rax
movaps %xmm3,%xmm2
movaps %xmm0,%xmm5
movaps %xmm4,%xmm0
jmp    11e8 <hsv_to_rgb+0xe8>
movaps %xmm4,%xmm2
movaps %xmm3,%xmm5
jmp    11e8 <hsv_to_rgb+0xe8>
movaps %xmm1,%xmm2
movaps %xmm0,%xmm5
movaps %xmm3,%xmm0
jmp    11e8 <hsv_to_rgb+0xe8>
movaps %xmm0,%xmm2
movaps %xmm4,%xmm5
movaps %xmm3,%xmm0
jmp    11e8 <hsv_to_rgb+0xe8>
movaps %xmm0,%xmm2
movaps %xmm3,%xmm5
movaps %xmm1,%xmm0
movss  0xe14(%rip),%xmm1
mulss  %xmm1,%xmm0
cvttss2si %xmm0,%eax
mov    %ax,(%rsi)
mulss  %xmm1,%xmm5
cvttss2si %xmm5,%eax
mov    %ax,(%rdx)
mulss  %xmm1,%xmm2
cvttss2si %xmm2,%eax
mov    %ax,(%rcx)
ret

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

LLVM IR (-O2):
define void @hsv_to_rgb(i32 %0, float %1, float %2, i16* nocapture writeonly %3, i16* nocapture writeonly %4, i16* nocapture writeonly %5) {
%7 = fcmp olt float %1, 0.000000e+00
%8 = select i1 %7, float 0.000000e+00, float %1
%9 = fcmp olt float %2, 0.000000e+00
%10 = select i1 %9, float 0.000000e+00, float %2
%11 = fcmp ogt float %8, 1.000000e+00
%12 = select i1 %11, float 1.000000e+00, float %8
%13 = fcmp ogt float %10, 1.000000e+00
%14 = select i1 %13, float 1.000000e+00, float %10
%15 = srem i32 %0, 360
%16 = sitofp i32 %15 to double
%17 = fdiv double %16, 6.000000e+01
%18 = fptrunc double %17 to float
%19 = fptosi float %18 to i32
%20 = sitofp i32 %19 to float
%21 = fsub float %18, %20
%22 = fsub float 1.000000e+00, %12
%23 = fmul float %14, %22
%24 = fneg float %12
%25 = tail call float @llvm.fmuladd.f32(float %24, float %21, float 1.000000e+00)
%26 = fmul float %14, %25
%27 = fsub float 1.000000e+00, %21
%28 = tail call float @llvm.fmuladd.f32(float %24, float %27, float 1.000000e+00)
%29 = fmul float %14, %28
switch i32 %19, label %34 [
i32 0, label %35
i32 1, label %30
i32 2, label %31
i32 3, label %32
i32 4, label %33
]
30: ; preds = %6
br label %35
31: ; preds = %6
br label %35
32: ; preds = %6
br label %35
33: ; preds = %6
br label %35
34: ; preds = %6
br label %35
35: ; preds = %6, %30, %32, %34, %33, %31
%36 = phi float [ %23, %30 ], [ %29, %31 ], [ %14, %32 ], [ %14, %33 ], [ %26, %34 ], [ %23, %6 ]
%37 = phi float [ %14, %30 ], [ %14, %31 ], [ %26, %32 ], [ %23, %33 ], [ %23, %34 ], [ %29, %6 ]
%38 = phi float [ %26, %30 ], [ %23, %31 ], [ %23, %32 ], [ %29, %33 ], [ %14, %34 ], [ %14, %6 ]
%39 = fmul float %38, 6.553500e+04
%40 = fptoui float %39 to i16
store i16 %40, i16* %3
%41 = fmul float %37, 6.553500e+04
%42 = fptoui float %41 to i16
store i16 %42, i16* %4
%43 = fmul float %36, 6.553500e+04
%44 = fptoui float %43 to i16
store i16 %44, i16* %5
ret void
}