double BitsEntropyRefine(int nonzeros, int sum, int max_val, double retval) {
  double mix;
  if (nonzeros < 5) {
    if (nonzeros <= 1) {
      return 0;
    }
    if (nonzeros == 2) {
      return 0.99 * sum + 0.01 * retval;
    }
    if (nonzeros == 3) {
      mix = 0.95;
    } else {
      mix = 0.7;
    }
  } else {
    mix = 0.627;
  }
  {
    double min_limit = 2 * sum - max_val;
    min_limit = mix * min_limit + (1.0 - mix) * retval;
    return (retval < min_limit) ? min_limit : retval;
  }
}


x86 assembly (clang, -O0):
<BitsEntropyRefine>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movsd  %xmm0,-0x20(%rbp)
cmpl   $0x5,-0xc(%rbp)
jge    1197 <BitsEntropyRefine+0x97>
cmpl   $0x1,-0xc(%rbp)
jg     1133 <BitsEntropyRefine+0x33>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1216 <BitsEntropyRefine+0x116>
cmpl   $0x2,-0xc(%rbp)
jne    1169 <BitsEntropyRefine+0x69>
cvtsi2sdl -0x10(%rbp),%xmm0
movsd  0xede(%rip),%xmm1
mulsd  -0x20(%rbp),%xmm1
movsd  0xec9(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1216 <BitsEntropyRefine+0x116>
cmpl   $0x3,-0xc(%rbp)
jne    1185 <BitsEntropyRefine+0x85>
movsd  0xe95(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    1192 <BitsEntropyRefine+0x92>
movsd  0xe7b(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    11a4 <BitsEntropyRefine+0xa4>
movsd  0xe61(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x10(%rbp),%eax
shl    $0x1,%eax
sub    -0x14(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm2
movsd  0xe50(%rip),%xmm1
subsd  -0x28(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1202 <BitsEntropyRefine+0x102>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    120c <BitsEntropyRefine+0x10c>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<BitsEntropyRefine>:
cmp    $0x4,%edi
jg     1138 <BitsEntropyRefine+0x38>
xorpd  %xmm1,%xmm1
cmp    $0x2,%edi
jl     1167 <BitsEntropyRefine+0x67>
cmp    $0x3,%edi
je     116c <BitsEntropyRefine+0x6c>
cmp    $0x2,%edi
jne    1176 <BitsEntropyRefine+0x76>
xorps  %xmm1,%xmm1
cvtsi2sd %esi,%xmm1
mulsd  0xee9(%rip),%xmm0
mulsd  0xee9(%rip),%xmm1
addsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
ret
movsd  0xec0(%rip),%xmm2
add    %esi,%esi
sub    %edx,%esi
xorps  %xmm1,%xmm1
cvtsi2sd %esi,%xmm1
movsd  0xed5(%rip),%xmm3
subsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm3
mulsd  %xmm2,%xmm1
addsd  %xmm3,%xmm1
maxsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
ret
movsd  0xe94(%rip),%xmm2
jmp    1140 <BitsEntropyRefine+0x40>
movsd  0xea2(%rip),%xmm2
jmp    1140 <BitsEntropyRefine+0x40>

LLVM IR (-O0):
define double @BitsEntropyRefine(i32 %0, i32 %1, i32 %2, double %3) {
%5 = alloca double
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
%10 = alloca double
%11 = alloca double
store i32 %0, i32* %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store double %3, double* %9
%12 = load i32, i32* %6
%13 = icmp slt i32 %12, 5
br i1 %13, label %14, label %33
14: ; preds = %4
%15 = load i32, i32* %6
%16 = icmp sle i32 %15, 1
br i1 %16, label %17, label %18
17: ; preds = %14
store double 0.000000e+00, double* %5
br label %56
18: ; preds = %14
%19 = load i32, i32* %6
%20 = icmp eq i32 %19, 2
br i1 %20, label %21, label %27
21: ; preds = %18
%22 = load i32, i32* %7
%23 = sitofp i32 %22 to double
%24 = load double, double* %9
%25 = fmul double 1.000000e-02, %24
%26 = call double @llvm.fmuladd.f64(double 0x3FEFAE147AE147AE, double %23, double %25)
store double %26, double* %5
br label %56
27: ; preds = %18
%28 = load i32, i32* %6
%29 = icmp eq i32 %28, 3
br i1 %29, label %30, label %31
30: ; preds = %27
store double 0x3FEE666666666666, double* %10
br label %32
31: ; preds = %27
store double 0x3FE6666666666666, double* %10
br label %32
32: ; preds = %31, %30
br label %34
33: ; preds = %4
store double 6.270000e-01, double* %10
br label %34
34: ; preds = %33, %32
%35 = load i32, i32* %7
%36 = mul nsw i32 2, %35
%37 = load i32, i32* %8
%38 = sub nsw i32 %36, %37
%39 = sitofp i32 %38 to double
store double %39, double* %11
%40 = load double, double* %10
%41 = load double, double* %11
%42 = load double, double* %10
%43 = fsub double 1.000000e+00, %42
%44 = load double, double* %9
%45 = fmul double %43, %44
%46 = call double @llvm.fmuladd.f64(double %40, double %41, double %45)
store double %46, double* %11
%47 = load double, double* %9
%48 = load double, double* %11
%49 = fcmp olt double %47, %48
br i1 %49, label %50, label %52
50: ; preds = %34
%51 = load double, double* %11
br label %54
52: ; preds = %34
%53 = load double, double* %9
br label %54
54: ; preds = %52, %50
%55 = phi double [ %51, %50 ], [ %53, %52 ]
store double %55, double* %5
br label %56
56: ; preds = %54, %21, %17
%57 = load double, double* %5
ret double %57
}

LLVM IR (-O2):
define double @BitsEntropyRefine(i32 %0, i32 %1, i32 %2, double %3) {
%5 = icmp slt i32 %0, 5
br i1 %5, label %6, label %14
6: ; preds = %4
%7 = icmp slt i32 %0, 2
br i1 %7, label %24, label %8
8: ; preds = %6
switch i32 %0, label %13 [
i32 2, label %9
i32 3, label %14
]
9: ; preds = %8
%10 = sitofp i32 %1 to double
%11 = fmul double %3, 1.000000e-02
%12 = tail call double @llvm.fmuladd.f64(double %10, double 0x3FEFAE147AE147AE, double %11)
br label %24
13: ; preds = %8
br label %14
14: ; preds = %4, %8, %13
%15 = phi double [ 0x3FE6666666666666, %13 ], [ 0x3FEE666666666666, %8 ], [ 6.270000e-01, %4 ]
%16 = shl nsw i32 %1, 1
%17 = sub nsw i32 %16, %2
%18 = sitofp i32 %17 to double
%19 = fsub double 1.000000e+00, %15
%20 = fmul double %19, %3
%21 = tail call double @llvm.fmuladd.f64(double %15, double %18, double %20)
%22 = fcmp ogt double %21, %3
%23 = select i1 %22, double %21, double %3
br label %24
24: ; preds = %6, %14, %9
%25 = phi double [ %12, %9 ], [ %23, %14 ], [ 0.000000e+00, %6 ]
ret double %25
}