double normalize(double value, double min, double max, double avg) {
  if (value <= min)
    return 0.0;
  if (value >= max)
    return 1.0;
  if (value < avg) {
    return 0.5 * (avg != min ? (value - min) / (avg - min) : 1);
  } else {
    return 0.5 * (avg != max ? 1 + (value - avg) / (max - avg) : 1);
  }
}


x86 assembly (clang, -O0):
<normalize>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     1139 <normalize+0x39>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    124a <normalize+0x14a>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jb     115b <normalize+0x5b>
movsd  0xeaf(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    124a <normalize+0x14a>
movsd  -0x10(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11d9 <normalize+0xd9>
movsd  -0x28(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jne    118a <normalize+0x8a>
jp     118a <normalize+0x8a>
jmp    11ac <normalize+0xac>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
subsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    11be <normalize+0xbe>
movsd  0xe4c(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    11be <normalize+0xbe>
movsd  -0x30(%rbp),%xmm1
movsd  0xe3d(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    124a <normalize+0x14a>
movsd  -0x28(%rbp),%xmm0
ucomisd -0x20(%rbp),%xmm0
jne    11f4 <normalize+0xf4>
jp     11f4 <normalize+0xf4>
jmp    1222 <normalize+0x122>
movsd  -0x10(%rbp),%xmm1
subsd  -0x28(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
divsd  %xmm0,%xmm1
movsd  0xdec(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1234 <normalize+0x134>
movsd  0xdd6(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1234 <normalize+0x134>
movsd  -0x38(%rbp),%xmm1
movsd  0xdc7(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<normalize>:
xorpd  %xmm4,%xmm4
ucomisd %xmm0,%xmm1
jae    115d <normalize+0x5d>
ucomisd %xmm2,%xmm0
jae    112c <normalize+0x2c>
ucomisd %xmm0,%xmm3
jbe    1135 <normalize+0x35>
ucomisd %xmm1,%xmm3
jne    111e <normalize+0x1e>
jnp    1162 <normalize+0x62>
subsd  %xmm1,%xmm0
subsd  %xmm1,%xmm3
divsd  %xmm3,%xmm0
jmp    1151 <normalize+0x51>
movsd  0xecc(%rip),%xmm0
ret
ucomisd %xmm2,%xmm3
jne    113d <normalize+0x3d>
jnp    1162 <normalize+0x62>
subsd  %xmm3,%xmm0
subsd  %xmm3,%xmm2
divsd  %xmm2,%xmm0
addsd  0xeaf(%rip),%xmm0
mulsd  0xeaf(%rip),%xmm0
movapd %xmm0,%xmm4
movapd %xmm4,%xmm0
ret
movsd  0xe9e(%rip),%xmm0
ret

LLVM IR (-O0):
define double @normalize(double %0, double %1, double %2, double %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
store double %0, double* %6
store double %1, double* %7
store double %2, double* %8
store double %3, double* %9
%10 = load double, double* %6
%11 = load double, double* %7
%12 = fcmp ole double %10, %11
br i1 %12, label %13, label %14
13: ; preds = %4
store double 0.000000e+00, double* %5
br label %56
14: ; preds = %4
%15 = load double, double* %6
%16 = load double, double* %8
%17 = fcmp oge double %15, %16
br i1 %17, label %18, label %19
18: ; preds = %14
store double 1.000000e+00, double* %5
br label %56
19: ; preds = %14
%20 = load double, double* %6
%21 = load double, double* %9
%22 = fcmp olt double %20, %21
br i1 %22, label %23, label %39
23: ; preds = %19
%24 = load double, double* %9
%25 = load double, double* %7
%26 = fcmp une double %24, %25
br i1 %26, label %27, label %35
27: ; preds = %23
%28 = load double, double* %6
%29 = load double, double* %7
%30 = fsub double %28, %29
%31 = load double, double* %9
%32 = load double, double* %7
%33 = fsub double %31, %32
%34 = fdiv double %30, %33
br label %36
35: ; preds = %23
br label %36
36: ; preds = %35, %27
%37 = phi double [ %34, %27 ], [ 1.000000e+00, %35 ]
%38 = fmul double 5.000000e-01, %37
store double %38, double* %5
br label %56
39: ; preds = %19
%40 = load double, double* %9
%41 = load double, double* %8
%42 = fcmp une double %40, %41
br i1 %42, label %43, label %52
43: ; preds = %39
%44 = load double, double* %6
%45 = load double, double* %9
%46 = fsub double %44, %45
%47 = load double, double* %8
%48 = load double, double* %9
%49 = fsub double %47, %48
%50 = fdiv double %46, %49
%51 = fadd double 1.000000e+00, %50
br label %53
52: ; preds = %39
br label %53
53: ; preds = %52, %43
%54 = phi double [ %51, %43 ], [ 1.000000e+00, %52 ]
%55 = fmul double 5.000000e-01, %54
store double %55, double* %5
br label %56
56: ; preds = %53, %36, %18, %13
%57 = load double, double* %5
ret double %57
}

LLVM IR (-O2):
define double @normalize(double %0, double %1, double %2, double %3) {
%5 = fcmp ugt double %0, %1
br i1 %5, label %6, label %25
6: ; preds = %4
%7 = fcmp ult double %0, %2
br i1 %7, label %8, label %25
8: ; preds = %6
%9 = fcmp olt double %0, %3
br i1 %9, label %10, label %17
10: ; preds = %8
%11 = fcmp une double %3, %1
br i1 %11, label %12, label %25
12: ; preds = %10
%13 = fsub double %0, %1
%14 = fsub double %3, %1
%15 = fdiv double %13, %14
%16 = fmul double %15, 5.000000e-01
br label %25
17: ; preds = %8
%18 = fcmp une double %3, %2
br i1 %18, label %19, label %25
19: ; preds = %17
%20 = fsub double %0, %3
%21 = fsub double %2, %3
%22 = fdiv double %20, %21
%23 = fadd double %22, 1.000000e+00
%24 = fmul double %23, 5.000000e-01
br label %25
25: ; preds = %19, %17, %12, %10, %6, %4
%26 = phi double [ 0.000000e+00, %4 ], [ 1.000000e+00, %6 ], [ %16, %12 ], [ 5.000000e-01, %10 ], [ %24, %19 ], [ 5.000000e-01, %17 ]
ret double %26
}