#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
unsigned char srgb(double);
void hsv(unsigned char *out, double h, double s, double v) {
  static int map[6][3] = {{0, 3, 1}, {2, 0, 1}, {1, 0, 3},
                          {1, 2, 0}, {3, 1, 0}, {0, 1, 2}};
  double h6 = h * 6;
  double f = h6 - (int)h6;
  double vars[4] = {v, v * (1 - s), v * (1 - (s * f)), v * (1 - (s * (1 - f)))};
  int i = ((int)h6 % 6 + 6) % 6;
  out[0] = srgb(vars[map[i][0]]);
  out[1] = srgb(vars[map[i][1]]);
  out[2] = srgb(vars[map[i][2]]);
}


x86 assembly (clang, -O0):
<hsv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  0xed5(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
cvttsd2si -0x28(%rbp),%eax
cvtsi2sd %eax,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe95(%rip),%xmm1
subsd  -0x18(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xe55(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  0xe36(%rip),%xmm2
subsd  -0x30(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xe0e(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
cvttsd2si -0x28(%rbp),%eax
mov    $0x6,%ecx
cltd
idiv   %ecx
mov    %edx,%eax
add    $0x6,%eax
mov    $0x6,%ecx
cltd
idiv   %ecx
mov    %edx,-0x54(%rbp)
movslq -0x54(%rbp),%rcx
lea    0x2e09(%rip),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq (%rax),%rax
movsd  -0x50(%rbp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
movslq -0x54(%rbp),%rcx
lea    0x2de1(%rip),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq 0x4(%rax),%rax
movsd  -0x50(%rbp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x1(%rax)
movslq -0x54(%rbp),%rcx
lea    0x2db7(%rip),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq 0x8(%rax),%rax
movsd  -0x50(%rbp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x2(%rax)
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<hsv>:
push   %r15
push   %r14
push   %rbx
sub    $0x20,%rsp
mulsd  0xedf(%rip),%xmm0
cvttsd2si %xmm0,%eax
cvttpd2dq %xmm0,%xmm3
cvtdq2pd %xmm3,%xmm3
mov    %rdi,%r14
subsd  %xmm3,%xmm0
movsd  %xmm2,(%rsp)
movsd  0xec7(%rip),%xmm3
movapd %xmm3,%xmm4
subsd  %xmm1,%xmm4
movapd %xmm3,%xmm5
subsd  %xmm0,%xmm5
mulsd  %xmm1,%xmm5
mulsd  %xmm0,%xmm1
movapd %xmm3,%xmm0
subsd  %xmm1,%xmm0
unpcklpd %xmm0,%xmm4
subsd  %xmm5,%xmm3
mulsd  %xmm2,%xmm3
unpcklpd %xmm2,%xmm2
mulpd  %xmm4,%xmm2
movupd %xmm2,0x8(%rsp)
movsd  %xmm3,0x18(%rsp)
cltq
imul   $0x2aaaaaab,%rax,%rcx
mov    %rcx,%rdx
shr    $0x3f,%rdx
shr    $0x20,%rcx
add    %edx,%ecx
add    %ecx,%ecx
lea    (%rcx,%rcx,2),%ecx
sub    %ecx,%eax
add    $0x6,%al
movzbl %al,%eax
imul   $0xab,%eax,%ecx
shr    $0x9,%ecx
and    $0xfffffffe,%ecx
lea    (%rcx,%rcx,2),%ecx
sub    %cl,%al
movzbl %al,%eax
lea    (%rax,%rax,2),%rbx
lea    0xe4e(%rip),%r15
movslq (%r15,%rbx,4),%rax
movsd  (%rsp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,(%r14)
movslq 0x4(%r15,%rbx,4),%rax
movsd  (%rsp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,0x1(%r14)
movslq 0x8(%r15,%rbx,4),%rax
movsd  (%rsp,%rax,8),%xmm0
call   1030 <srgb@plt>
mov    %al,0x2(%r14)
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@hsv.map = internal global [6 x [3 x i32]] [[3 x i32] [i32 0, i32 3, i32 1], [3 x i32] [i32 2, i32 0, i32 1], [3 x i32] [i32 1, i32 0, i32 3], [3 x i32] [i32 1, i32 2, i32 0], [3 x i32] [i32 3, i32 1, i32 0], [3 x i32] [i32 0, i32 1, i32 2]]
define void @hsv(i8* %0, double %1, double %2, double %3) {
%5 = alloca i8*
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca [4 x double]
%12 = alloca i32
store i8* %0, i8** %5
store double %1, double* %6
store double %2, double* %7
store double %3, double* %8
%13 = load double, double* %6
%14 = fmul double %13, 6.000000e+00
store double %14, double* %9
%15 = load double, double* %9
%16 = load double, double* %9
%17 = fptosi double %16 to i32
%18 = sitofp i32 %17 to double
%19 = fsub double %15, %18
store double %19, double* %10
%20 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 0
%21 = load double, double* %8
store double %21, double* %20
%22 = getelementptr inbounds double, double* %20, i64 1
%23 = load double, double* %8
%24 = load double, double* %7
%25 = fsub double 1.000000e+00, %24
%26 = fmul double %23, %25
store double %26, double* %22
%27 = getelementptr inbounds double, double* %22, i64 1
%28 = load double, double* %8
%29 = load double, double* %7
%30 = load double, double* %10
%31 = fneg double %29
%32 = call double @llvm.fmuladd.f64(double %31, double %30, double 1.000000e+00)
%33 = fmul double %28, %32
store double %33, double* %27
%34 = getelementptr inbounds double, double* %27, i64 1
%35 = load double, double* %8
%36 = load double, double* %7
%37 = load double, double* %10
%38 = fsub double 1.000000e+00, %37
%39 = fneg double %36
%40 = call double @llvm.fmuladd.f64(double %39, double %38, double 1.000000e+00)
%41 = fmul double %35, %40
store double %41, double* %34
%42 = load double, double* %9
%43 = fptosi double %42 to i32
%44 = srem i32 %43, 6
%45 = add nsw i32 %44, 6
%46 = srem i32 %45, 6
store i32 %46, i32* %12
%47 = load i32, i32* %12
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %48
%50 = getelementptr inbounds [3 x i32], [3 x i32]* %49, i64 0, i64 0
%51 = load i32, i32* %50
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 %52
%54 = load double, double* %53
%55 = call zeroext i8 @srgb(double %54)
%56 = load i8*, i8** %5
%57 = getelementptr inbounds i8, i8* %56, i64 0
store i8 %55, i8* %57
%58 = load i32, i32* %12
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %59
%61 = getelementptr inbounds [3 x i32], [3 x i32]* %60, i64 0, i64 1
%62 = load i32, i32* %61
%63 = sext i32 %62 to i64
%64 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 %63
%65 = load double, double* %64
%66 = call zeroext i8 @srgb(double %65)
%67 = load i8*, i8** %5
%68 = getelementptr inbounds i8, i8* %67, i64 1
store i8 %66, i8* %68
%69 = load i32, i32* %12
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %70
%72 = getelementptr inbounds [3 x i32], [3 x i32]* %71, i64 0, i64 2
%73 = load i32, i32* %72
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 %74
%76 = load double, double* %75
%77 = call zeroext i8 @srgb(double %76)
%78 = load i8*, i8** %5
%79 = getelementptr inbounds i8, i8* %78, i64 2
store i8 %77, i8* %79
ret void
}

LLVM IR (-O2):
@hsv.map = internal unnamed_addr constant [6 x [3 x i32]] [[3 x i32] [i32 0, i32 3, i32 1], [3 x i32] [i32 2, i32 0, i32 1], [3 x i32] [i32 1, i32 0, i32 3], [3 x i32] [i32 1, i32 2, i32 0], [3 x i32] [i32 3, i32 1, i32 0], [3 x i32] [i32 0, i32 1, i32 2]]
define void @hsv(i8* nocapture writeonly %0, double %1, double %2, double %3) {
%5 = alloca [4 x double]
%6 = fmul double %1, 6.000000e+00
%7 = fptosi double %6 to i32
%8 = sitofp i32 %7 to double
%9 = fsub double %6, %8
%10 = bitcast [4 x double]* %5 to i8*
%11 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 0
store double %3, double* %11
%12 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 1
%13 = fsub double 1.000000e+00, %2
%14 = fneg double %2
%15 = tail call double @llvm.fmuladd.f64(double %14, double %9, double 1.000000e+00)
%16 = insertelement <2 x double> poison, double %13, i64 0
%17 = insertelement <2 x double> %16, double %15, i64 1
%18 = insertelement <2 x double> poison, double %3, i64 0
%19 = shufflevector <2 x double> %18, <2 x double> poison, <2 x i32> zeroinitializer
%20 = fmul <2 x double> %17, %19
%21 = bitcast double* %12 to <2 x double>*
store <2 x double> %20, <2 x double>* %21
%22 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 3
%23 = fsub double 1.000000e+00, %9
%24 = tail call double @llvm.fmuladd.f64(double %14, double %23, double 1.000000e+00)
%25 = fmul double %24, %3
store double %25, double* %22
%26 = srem i32 %7, 6
%27 = trunc i32 %26 to i8
%28 = add nsw i8 %27, 6
%29 = urem i8 %28, 6
%30 = zext i8 %29 to i64
%31 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %30, i64 0
%32 = load i32, i32* %31
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 %33
%35 = load double, double* %34
%36 = tail call zeroext i8 @srgb(double %35)
store i8 %36, i8* %0
%37 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %30, i64 1
%38 = load i32, i32* %37
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 %39
%41 = load double, double* %40
%42 = tail call zeroext i8 @srgb(double %41)
%43 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %42, i8* %43
%44 = getelementptr inbounds [6 x [3 x i32]], [6 x [3 x i32]]* @hsv.map, i64 0, i64 %30, i64 2
%45 = load i32, i32* %44
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds [4 x double], [4 x double]* %5, i64 0, i64 %46
%48 = load double, double* %47
%49 = tail call zeroext i8 @srgb(double %48)
%50 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %49, i8* %50
ret void
}