void hsv_to_rgb(int h, double s, double v, unsigned short *r, unsigned short *g,
                unsigned short *b) {
  double H, S, V, R, G, B;
  double p1, p2, p3;
  double 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
push   %rax
mov    %edi,-0x4(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
mov    %rdx,-0x28(%rbp)
mov    %rcx,-0x30(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1134 <hsv_to_rgb+0x34>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    114a <hsv_to_rgb+0x4a>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xea9(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    116e <hsv_to_rgb+0x6e>
movsd  0xe97(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe85(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1192 <hsv_to_rgb+0x92>
movsd  0xe73(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x168,%ecx
cltd
idiv   %ecx
cvtsi2sd %edx,%xmm0
movsd  0xe4b(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
cvttsd2si -0x38(%rbp),%eax
mov    %eax,-0x84(%rbp)
movsd  -0x38(%rbp),%xmm0
cvtsi2sdl -0x84(%rbp),%xmm1
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  0xe0c(%rip),%xmm1
subsd  -0x40(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
movsd  -0x80(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xdcc(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
movsd  0xdad(%rip),%xmm2
subsd  -0x80(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xd85(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
cmpl   $0x0,-0x84(%rbp)
jne    12b8 <hsv_to_rgb+0x1b8>
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    13aa <hsv_to_rgb+0x2aa>
cmpl   $0x1,-0x84(%rbp)
jne    12e8 <hsv_to_rgb+0x1e8>
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    13a5 <hsv_to_rgb+0x2a5>
cmpl   $0x2,-0x84(%rbp)
jne    1318 <hsv_to_rgb+0x218>
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    13a0 <hsv_to_rgb+0x2a0>
cmpl   $0x3,-0x84(%rbp)
jne    1348 <hsv_to_rgb+0x248>
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    139b <hsv_to_rgb+0x29b>
cmpl   $0x4,-0x84(%rbp)
jne    1378 <hsv_to_rgb+0x278>
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    1396 <hsv_to_rgb+0x296>
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    139b <hsv_to_rgb+0x29b>
jmp    13a0 <hsv_to_rgb+0x2a0>
jmp    13a5 <hsv_to_rgb+0x2a5>
jmp    13aa <hsv_to_rgb+0x2aa>
movsd  -0x50(%rbp),%xmm0
movsd  0xc59(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,%cx
mov    -0x20(%rbp),%rax
mov    %cx,(%rax)
movsd  -0x58(%rbp),%xmm0
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
movsd  -0x60(%rbp),%xmm0
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,%cx
mov    -0x30(%rbp),%rax
mov    %cx,(%rax)
add    $0x8,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<hsv_to_rgb>:
xorpd  %xmm3,%xmm3
xorpd  %xmm4,%xmm4
maxsd  %xmm0,%xmm4
maxsd  %xmm1,%xmm3
movsd  0xee8(%rip),%xmm1
movapd %xmm1,%xmm2
minsd  %xmm4,%xmm2
movapd %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
cvtsi2sd %eax,%xmm5
divsd  0xeb3(%rip),%xmm5
cvttsd2si %xmm5,%eax
cvttpd2dq %xmm5,%xmm4
cvtdq2pd %xmm4,%xmm4
minsd  %xmm3,%xmm0
subsd  %xmm4,%xmm5
movapd %xmm1,%xmm3
subsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm3
movapd %xmm2,%xmm6
mulsd  %xmm5,%xmm6
movapd %xmm1,%xmm4
subsd  %xmm6,%xmm4
mulsd  %xmm0,%xmm4
cmp    $0x4,%eax
ja     11c8 <hsv_to_rgb+0xc8>
movapd %xmm1,%xmm6
subsd  %xmm5,%xmm6
mulsd  %xmm6,%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm1
lea    0xe6f(%rip),%rdi
movslq (%rdi,%rax,4),%rax
add    %rdi,%rax
movapd %xmm3,%xmm2
movapd %xmm1,%xmm5
jmp    *%rax
movapd %xmm3,%xmm2
movapd %xmm0,%xmm5
movapd %xmm4,%xmm0
jmp    11fa <hsv_to_rgb+0xfa>
movapd %xmm4,%xmm2
movapd %xmm3,%xmm5
jmp    11fa <hsv_to_rgb+0xfa>
movapd %xmm1,%xmm2
movapd %xmm0,%xmm5
movapd %xmm3,%xmm0
jmp    11fa <hsv_to_rgb+0xfa>
movapd %xmm0,%xmm2
movapd %xmm4,%xmm5
movapd %xmm3,%xmm0
jmp    11fa <hsv_to_rgb+0xfa>
movapd %xmm0,%xmm2
movapd %xmm3,%xmm5
movapd %xmm1,%xmm0
movsd  0xe0e(%rip),%xmm1
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,(%rsi)
mulsd  %xmm1,%xmm5
cvttsd2si %xmm5,%eax
mov    %ax,(%rdx)
mulsd  %xmm1,%xmm2
cvttsd2si %xmm2,%eax
mov    %ax,(%rcx)
ret

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

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