double hf(double v, int c) {
  v -= c;
  while (v < -3)
    v += 6;
  while (3 < v)
    v -= 6;
  if (-1 <= v && v <= 1)
    return 1;
  if (-2 < v && v < -1)
    return v + 2;
  if (1 < v && v < 2)
    return 2 - v;
  return 0;
}


x86 assembly (clang, -O0):
<hf>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
cvtsi2sdl -0x14(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xed9(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1149 <hf+0x49>
movsd  0xef6(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    111f <hf+0x1f>
jmp    114e <hf+0x4e>
movsd  -0x10(%rbp),%xmm0
movsd  0xead(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1180 <hf+0x80>
movsd  -0x10(%rbp),%xmm0
movsd  0xebe(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    114e <hf+0x4e>
movsd  -0x10(%rbp),%xmm0
movsd  0xe83(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11bc <hf+0xbc>
movsd  0xe79(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     11bc <hf+0xbc>
movsd  0xe66(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1246 <hf+0x146>
movsd  -0x10(%rbp),%xmm0
movsd  0xe57(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11fd <hf+0xfd>
movsd  0xe35(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11fd <hf+0xfd>
movsd  0xe3a(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1246 <hf+0x146>
movsd  -0x10(%rbp),%xmm0
movsd  0xe0e(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    123e <hf+0x13e>
movsd  0xe0c(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    123e <hf+0x13e>
movsd  0xdf9(%rip),%xmm0
subsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1246 <hf+0x146>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<hf>:
cvtsi2sd %edi,%xmm1
subsd  %xmm1,%xmm0
movsd  0xef0(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    112a <hf+0x2a>
movsd  0xeea(%rip),%xmm2
xchg   %ax,%ax
addsd  %xmm2,%xmm0
ucomisd %xmm0,%xmm1
ja     1120 <hf+0x20>
ucomisd 0xede(%rip),%xmm0
jbe    115a <hf+0x5a>
movsd  0xedc(%rip),%xmm1
movsd  0xecc(%rip),%xmm2
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
addsd  %xmm1,%xmm0
ucomisd %xmm2,%xmm0
ja     1150 <hf+0x50>
ucomisd 0xebe(%rip),%xmm0
jb     117b <hf+0x7b>
movsd  0xebc(%rip),%xmm1
ucomisd %xmm0,%xmm1
jb     117b <hf+0x7b>
movsd  0xeae(%rip),%xmm0
ret
ucomisd 0xead(%rip),%xmm0
jbe    119c <hf+0x9c>
movsd  0xe93(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    119c <hf+0x9c>
addsd  0xe9d(%rip),%xmm0
ret
movsd  0xe94(%rip),%xmm2
movapd %xmm0,%xmm1
cmpltsd %xmm2,%xmm1
subsd  %xmm0,%xmm2
andpd  %xmm1,%xmm2
movsd  0xe6b(%rip),%xmm1
cmpltsd %xmm0,%xmm1
andpd  %xmm2,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @hf(double %0, i32 %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca i32
store double %0, double* %4
store i32 %1, i32* %5
%6 = load i32, i32* %5
%7 = sitofp i32 %6 to double
%8 = load double, double* %4
%9 = fsub double %8, %7
store double %9, double* %4
br label %10
10: ; preds = %13, %2
%11 = load double, double* %4
%12 = fcmp olt double %11, -3.000000e+00
br i1 %12, label %13, label %16
13: ; preds = %10
%14 = load double, double* %4
%15 = fadd double %14, 6.000000e+00
store double %15, double* %4
br label %10
16: ; preds = %10
br label %17
17: ; preds = %20, %16
%18 = load double, double* %4
%19 = fcmp olt double 3.000000e+00, %18
br i1 %19, label %20, label %23
20: ; preds = %17
%21 = load double, double* %4
%22 = fsub double %21, 6.000000e+00
store double %22, double* %4
br label %17
23: ; preds = %17
%24 = load double, double* %4
%25 = fcmp ole double -1.000000e+00, %24
br i1 %25, label %26, label %30
26: ; preds = %23
%27 = load double, double* %4
%28 = fcmp ole double %27, 1.000000e+00
br i1 %28, label %29, label %30
29: ; preds = %26
store double 1.000000e+00, double* %3
br label %49
30: ; preds = %26, %23
%31 = load double, double* %4
%32 = fcmp olt double -2.000000e+00, %31
br i1 %32, label %33, label %39
33: ; preds = %30
%34 = load double, double* %4
%35 = fcmp olt double %34, -1.000000e+00
br i1 %35, label %36, label %39
36: ; preds = %33
%37 = load double, double* %4
%38 = fadd double %37, 2.000000e+00
store double %38, double* %3
br label %49
39: ; preds = %33, %30
%40 = load double, double* %4
%41 = fcmp olt double 1.000000e+00, %40
br i1 %41, label %42, label %48
42: ; preds = %39
%43 = load double, double* %4
%44 = fcmp olt double %43, 2.000000e+00
br i1 %44, label %45, label %48
45: ; preds = %42
%46 = load double, double* %4
%47 = fsub double 2.000000e+00, %46
store double %47, double* %3
br label %49
48: ; preds = %42, %39
store double 0.000000e+00, double* %3
br label %49
49: ; preds = %48, %45, %36, %29
%50 = load double, double* %3
ret double %50
}

LLVM IR (-O2):
define double @hf(double %0, i32 %1) {
%3 = sitofp i32 %1 to double
%4 = fsub double %0, %3
%5 = fcmp olt double %4, -3.000000e+00
br i1 %5, label %9, label %6
6: ; preds = %9, %2
%7 = phi double [ %4, %2 ], [ %11, %9 ]
%8 = fcmp ogt double %7, 3.000000e+00
br i1 %8, label %13, label %17
9: ; preds = %2, %9
%10 = phi double [ %11, %9 ], [ %4, %2 ]
%11 = fadd double %10, 6.000000e+00
%12 = fcmp olt double %11, -3.000000e+00
br i1 %12, label %9, label %6
13: ; preds = %6, %13
%14 = phi double [ %15, %13 ], [ %7, %6 ]
%15 = fadd double %14, -6.000000e+00
%16 = fcmp ogt double %15, 3.000000e+00
br i1 %16, label %13, label %17
17: ; preds = %13, %6
%18 = phi double [ %7, %6 ], [ %15, %13 ]
%19 = fcmp oge double %18, -1.000000e+00
%20 = fcmp ole double %18, 1.000000e+00
%21 = and i1 %19, %20
br i1 %21, label %34, label %22
22: ; preds = %17
%23 = fcmp ogt double %18, -2.000000e+00
%24 = fcmp olt double %18, -1.000000e+00
%25 = and i1 %23, %24
br i1 %25, label %26, label %28
26: ; preds = %22
%27 = fadd double %18, 2.000000e+00
br label %34
28: ; preds = %22
%29 = fcmp ogt double %18, 1.000000e+00
%30 = fcmp olt double %18, 2.000000e+00
%31 = and i1 %29, %30
%32 = fsub double 2.000000e+00, %18
%33 = select i1 %31, double %32, double 0.000000e+00
br label %34
34: ; preds = %28, %17, %26
%35 = phi double [ %27, %26 ], [ 1.000000e+00, %17 ], [ %33, %28 ]
ret double %35
}