#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 */
double logl(long);
double stats_2_entropy(long count, long total) {
  static long init = 0;
  static double loglookups[256][256];
  double value;
  if (total <= 0.0)
    return (1.00);
  if (count >= total)
    return (0.0);
  if (init == 0) {
    long i, j;
    init = 1;
    for (i = 0; i < 256; i++)
      for (j = 0; j < 256; j++)
        loglookups[i][j] = -1;
  }
  if (count < 256 && total < 256) {
    value = loglookups[count][total];
    if (value > 0.0)
      return value;
  }
  value = (-logl((count + 0.0000000000000000001) /
                 (total + 0.0000000000000000001))) /
          0.69314718;
  if (count < 256 && total < 256)
    loglookups[count][total] = value;
  return (value);
}


x86 assembly (clang, -O0):
<stats_2_entropy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
cvtsi2sdq -0x18(%rbp),%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jb     1145 <stats_2_entropy+0x35>
movsd  0xedd(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f6 <stats_2_entropy+0x1e6>
mov    -0x10(%rbp),%rax
cmp    -0x18(%rbp),%rax
jl     1160 <stats_2_entropy+0x50>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f6 <stats_2_entropy+0x1e6>
cmpq   $0x0,0x2ed8(%rip)
jne    11f4 <stats_2_entropy+0xe4>
movq   $0x1,0x2ec7(%rip)
movq   $0x0,-0x28(%rbp)
cmpq   $0x100,-0x28(%rbp)
jge    11ef <stats_2_entropy+0xdf>
movq   $0x0,-0x30(%rbp)
cmpq   $0x100,-0x30(%rbp)
jge    11d9 <stats_2_entropy+0xc9>
mov    -0x28(%rbp),%rcx
lea    0x2ea0(%rip),%rax
shl    $0xb,%rcx
add    %rcx,%rax
mov    -0x30(%rbp),%rcx
movsd  0xe4d(%rip),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1197 <stats_2_entropy+0x87>
jmp    11de <stats_2_entropy+0xce>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1181 <stats_2_entropy+0x71>
jmp    11f4 <stats_2_entropy+0xe4>
cmpq   $0x100,-0x10(%rbp)
jge    1256 <stats_2_entropy+0x146>
cmpq   $0x100,-0x18(%rbp)
jge    1256 <stats_2_entropy+0x146>
mov    -0x10(%rbp),%rcx
lea    0x2e35(%rip),%rax
shl    $0xb,%rcx
add    %rcx,%rax
mov    -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    1251 <stats_2_entropy+0x141>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f6 <stats_2_entropy+0x1e6>
jmp    1256 <stats_2_entropy+0x146>
cvtsi2sdq -0x10(%rbp),%xmm0
movsd  0xda4(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsi2sdq -0x18(%rbp),%xmm1
movsd  0xd92(%rip),%xmm2
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rdi
call   1030 <logl@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xd59(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
cmpq   $0x100,-0x10(%rbp)
jge    12ec <stats_2_entropy+0x1dc>
cmpq   $0x100,-0x18(%rbp)
jge    12ec <stats_2_entropy+0x1dc>
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rcx
lea    0x2d74(%rip),%rax
shl    $0xb,%rcx
add    %rcx,%rax
mov    -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<stats_2_entropy>:
push   %rbp
push   %r14
push   %rbx
test   %rsi,%rsi
jle    124d <stats_2_entropy+0x13d>
mov    %rsi,%rbx
mov    %rdi,%r14
xorpd  %xmm0,%xmm0
cmp    %rsi,%rdi
jge    1255 <stats_2_entropy+0x145>
cmpb   $0x0,0x2f09(%rip)
jne    11bf <stats_2_entropy+0xaf>
movb   $0x1,0x2efc(%rip)
lea    0x2f75(%rip),%rax
xor    %ecx,%ecx
movapd 0xecb(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nop
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movapd %xmm0,-0x70(%rax,%rdx,8)
movapd %xmm0,-0x60(%rax,%rdx,8)
movapd %xmm0,-0x50(%rax,%rdx,8)
movapd %xmm0,-0x40(%rax,%rdx,8)
movapd %xmm0,-0x30(%rax,%rdx,8)
movapd %xmm0,-0x20(%rax,%rdx,8)
movapd %xmm0,-0x10(%rax,%rdx,8)
movapd %xmm0,(%rax,%rdx,8)
add    $0x10,%rdx
cmp    $0x100,%rdx
jne    1170 <stats_2_entropy+0x60>
add    $0x1,%rcx
add    $0x800,%rax
cmp    $0x100,%rcx
jne    1160 <stats_2_entropy+0x50>
cmp    $0x100,%r14
setl   %al
cmp    $0x100,%rbx
setl   %bpl
and    %al,%bpl
cmp    $0x1,%bpl
jne    11fd <stats_2_entropy+0xed>
mov    %r14,%rax
shl    $0xb,%rax
lea    0x2e65(%rip),%rcx
add    %rax,%rcx
movsd  (%rcx,%rbx,8),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
ja     1255 <stats_2_entropy+0x145>
xorps  %xmm0,%xmm0
cvtsi2sd %rbx,%xmm0
xorps  %xmm1,%xmm1
cvtsi2sd %r14,%xmm1
movsd  0xdf3(%rip),%xmm2
addsd  %xmm2,%xmm1
addsd  %xmm2,%xmm0
divsd  %xmm0,%xmm1
cvttsd2si %xmm1,%rdi
call   1030 <logl@plt>
divsd  0xddd(%rip),%xmm0
test   %bpl,%bpl
je     1255 <stats_2_entropy+0x145>
shl    $0xb,%r14
lea    0x2e0d(%rip),%rax
add    %r14,%rax
movsd  %xmm0,(%rax,%rbx,8)
jmp    1255 <stats_2_entropy+0x145>
movsd  0xdab(%rip),%xmm0
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
@stats_2_entropy.init = internal global i64 0
@stats_2_entropy.loglookups = internal global [256 x [256 x double]] zeroinitializer
define double @stats_2_entropy(i64 %0, i64 %1) {
%3 = alloca double
%4 = alloca i64
%5 = alloca i64
%6 = alloca double
%7 = alloca i64
%8 = alloca i64
store i64 %0, i64* %4
store i64 %1, i64* %5
%9 = load i64, i64* %5
%10 = sitofp i64 %9 to double
%11 = fcmp ole double %10, 0.000000e+00
br i1 %11, label %12, label %13
12: ; preds = %2
store double 1.000000e+00, double* %3
br label %84
13: ; preds = %2
%14 = load i64, i64* %4
%15 = load i64, i64* %5
%16 = icmp sge i64 %14, %15
br i1 %16, label %17, label %18
17: ; preds = %13
store double 0.000000e+00, double* %3
br label %84
18: ; preds = %13
%19 = load i64, i64* @stats_2_entropy.init
%20 = icmp eq i64 %19, 0
br i1 %20, label %21, label %42
21: ; preds = %18
store i64 1, i64* @stats_2_entropy.init
store i64 0, i64* %7
br label %22
22: ; preds = %38, %21
%23 = load i64, i64* %7
%24 = icmp slt i64 %23, 256
br i1 %24, label %25, label %41
25: ; preds = %22
store i64 0, i64* %8
br label %26
26: ; preds = %34, %25
%27 = load i64, i64* %8
%28 = icmp slt i64 %27, 256
br i1 %28, label %29, label %37
29: ; preds = %26
%30 = load i64, i64* %7
%31 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %30
%32 = load i64, i64* %8
%33 = getelementptr inbounds [256 x double], [256 x double]* %31, i64 0, i64 %32
store double -1.000000e+00, double* %33
br label %34
34: ; preds = %29
%35 = load i64, i64* %8
%36 = add nsw i64 %35, 1
store i64 %36, i64* %8
br label %26
37: ; preds = %26
br label %38
38: ; preds = %37
%39 = load i64, i64* %7
%40 = add nsw i64 %39, 1
store i64 %40, i64* %7
br label %22
41: ; preds = %22
br label %42
42: ; preds = %41, %18
%43 = load i64, i64* %4
%44 = icmp slt i64 %43, 256
br i1 %44, label %45, label %59
45: ; preds = %42
%46 = load i64, i64* %5
%47 = icmp slt i64 %46, 256
br i1 %47, label %48, label %59
48: ; preds = %45
%49 = load i64, i64* %4
%50 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %49
%51 = load i64, i64* %5
%52 = getelementptr inbounds [256 x double], [256 x double]* %50, i64 0, i64 %51
%53 = load double, double* %52
store double %53, double* %6
%54 = load double, double* %6
%55 = fcmp ogt double %54, 0.000000e+00
br i1 %55, label %56, label %58
56: ; preds = %48
%57 = load double, double* %6
store double %57, double* %3
br label %84
58: ; preds = %48
br label %59
59: ; preds = %58, %45, %42
%60 = load i64, i64* %4
%61 = sitofp i64 %60 to double
%62 = fadd double %61, 0x3BFD83C94FB6D2AC
%63 = load i64, i64* %5
%64 = sitofp i64 %63 to double
%65 = fadd double %64, 0x3BFD83C94FB6D2AC
%66 = fdiv double %62, %65
%67 = fptosi double %66 to i64
%68 = call double @logl(i64 %67)
%69 = fneg double %68
%70 = fdiv double %69, 0x3FE62E42FEAD449C
store double %70, double* %6
%71 = load i64, i64* %4
%72 = icmp slt i64 %71, 256
br i1 %72, label %73, label %82
73: ; preds = %59
%74 = load i64, i64* %5
%75 = icmp slt i64 %74, 256
br i1 %75, label %76, label %82
76: ; preds = %73
%77 = load double, double* %6
%78 = load i64, i64* %4
%79 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %78
%80 = load i64, i64* %5
%81 = getelementptr inbounds [256 x double], [256 x double]* %79, i64 0, i64 %80
store double %77, double* %81
br label %82
82: ; preds = %76, %73, %59
%83 = load double, double* %6
store double %83, double* %3
br label %84
84: ; preds = %82, %56, %17, %12
%85 = load double, double* %3
ret double %85
}

LLVM IR (-O2):
@stats_2_entropy.init = internal unnamed_addr global i1 false
@stats_2_entropy.loglookups = internal unnamed_addr global [256 x [256 x double]] zeroinitializer
define double @stats_2_entropy(i64 %0, i64 %1) {
%3 = sitofp i64 %1 to double
%4 = icmp slt i64 %1, 1
br i1 %4, label %56, label %5
5: ; preds = %2
%6 = icmp slt i64 %0, %1
br i1 %6, label %7, label %56
7: ; preds = %5
%8 = load i1, i1* @stats_2_entropy.init
br i1 %8, label %38, label %9
9: ; preds = %7
store i1 true, i1* @stats_2_entropy.init
br label %10
10: ; preds = %35, %9
%11 = phi i64 [ 0, %9 ], [ %36, %35 ]
br label %12
12: ; preds = %12, %10
%13 = phi i64 [ 0, %10 ], [ %33, %12 ]
%14 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %11, i64 %13
%15 = bitcast double* %14 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %15
%16 = getelementptr inbounds double, double* %14, i64 2
%17 = bitcast double* %16 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %17
%18 = or i64 %13, 4
%19 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %11, i64 %18
%20 = bitcast double* %19 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %20
%21 = getelementptr inbounds double, double* %19, i64 2
%22 = bitcast double* %21 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %22
%23 = or i64 %13, 8
%24 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %11, i64 %23
%25 = bitcast double* %24 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %25
%26 = getelementptr inbounds double, double* %24, i64 2
%27 = bitcast double* %26 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %27
%28 = or i64 %13, 12
%29 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %11, i64 %28
%30 = bitcast double* %29 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %30
%31 = getelementptr inbounds double, double* %29, i64 2
%32 = bitcast double* %31 to <2 x double>*
store <2 x double> <double -1.000000e+00, double -1.000000e+00>, <2 x double>* %32
%33 = add nuw nsw i64 %13, 16
%34 = icmp eq i64 %33, 256
br i1 %34, label %35, label %12
35: ; preds = %12
%36 = add nuw nsw i64 %11, 1
%37 = icmp eq i64 %36, 256
br i1 %37, label %38, label %10
38: ; preds = %35, %7
%39 = icmp slt i64 %0, 256
%40 = icmp slt i64 %1, 256
%41 = and i1 %39, %40
br i1 %41, label %42, label %46
42: ; preds = %38
%43 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %0, i64 %1
%44 = load double, double* %43
%45 = fcmp ogt double %44, 0.000000e+00
br i1 %45, label %56, label %46
46: ; preds = %42, %38
%47 = sitofp i64 %0 to double
%48 = fadd double %47, 0x3BFD83C94FB6D2AC
%49 = fadd double %3, 0x3BFD83C94FB6D2AC
%50 = fdiv double %48, %49
%51 = fptosi double %50 to i64
%52 = tail call double @logl(i64 %51)
%53 = fdiv double %52, 0xBFE62E42FEAD449C
br i1 %41, label %54, label %56
54: ; preds = %46
%55 = getelementptr inbounds [256 x [256 x double]], [256 x [256 x double]]* @stats_2_entropy.loglookups, i64 0, i64 %0, i64 %1
store double %53, double* %55
br label %56
56: ; preds = %46, %54, %42, %5, %2
%57 = phi double [ 1.000000e+00, %2 ], [ 0.000000e+00, %5 ], [ %44, %42 ], [ %53, %54 ], [ %53, %46 ]
ret double %57
}