#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 */
float bin_above_threshold(float, float);
float binary_act_filter(float, float, float, float const);
double fabs(float const);
void threshold_bins(float bins[4], float filter_state[4], float thresholds[4]) {
  const float cutoffs[4] = {0.04, 0.04, 0.04, 0.04};
  const float goal[4] = {0.3, 0.3, 0.3, 0.1};
  for (int i = 0; i < 4; i++) {
    bins[i] = bin_above_threshold(bins[i], thresholds[i]);
    filter_state[i] =
        binary_act_filter(bins[i], thresholds[i], filter_state[i], cutoffs[i]);
    const float update = (goal[i] - filter_state[i]) / fabs(filter_state[i]);
    if (fabs(update) > 0.05)
      thresholds[i] -= 0.001 * update;
    if (thresholds[i] > 0.9)
      thresholds[i] = 0.9;
    else if (thresholds[i] < 0.02)
      thresholds[i] = 0.02;
  }
}


x86 assembly (clang, -O0):
<threshold_bins>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    0xee5(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xee2(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xedf(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    0xedc(%rip),%rax
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x44(%rbp)
cmpl   $0x4,-0x44(%rbp)
jge    1313 <threshold_bins+0x1e3>
mov    -0x8(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
call   1030 <bin_above_threshold@plt>
mov    -0x8(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x8(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movslq -0x44(%rbp),%rax
movss  -0x30(%rbp,%rax,4),%xmm3
call   1050 <binary_act_filter@plt>
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movslq -0x44(%rbp),%rax
movss  -0x40(%rbp,%rax,4),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x48(%rbp),%xmm0
call   1040 <fabs@plt>
movsd  0xdb7(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1286 <threshold_bins+0x156>
movss  -0x48(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm1
movsd  0xd93(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd71(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12c3 <threshold_bins+0x193>
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  0xd6b(%rip),%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    1300 <threshold_bins+0x1d0>
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd3c(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    12fb <threshold_bins+0x1cb>
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
movss  0xd2a(%rip),%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    1300 <threshold_bins+0x1d0>
jmp    1305 <threshold_bins+0x1d5>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    1177 <threshold_bins+0x47>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<threshold_bins>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%r12
mov    %rsi,%r14
mov    %rdi,%r15
xor    %ebx,%ebx
lea    0xee3(%rip),%r13
lea    0xeec(%rip),%rbp
jmp    1174 <threshold_bins+0x44>
cs nopw 0x0(%rax,%rax,1)
movss  %xmm0,(%r12,%rbx,1)
add    $0x4,%rbx
cmp    $0x10,%rbx
je     1252 <threshold_bins+0x122>
movss  (%r15,%rbx,1),%xmm0
movss  (%r12,%rbx,1),%xmm1
call   1030 <bin_above_threshold@plt>
movss  %xmm0,(%r15,%rbx,1)
movss  (%r12,%rbx,1),%xmm1
movss  (%r14,%rbx,1),%xmm2
movss  (%rbx,%r13,1),%xmm3
call   1050 <binary_act_filter@plt>
movss  %xmm0,(%r14,%rbx,1)
movss  (%rbx,%rbp,1),%xmm1
subss  %xmm0,%xmm1
cvtss2sd %xmm1,%xmm1
movsd  %xmm1,(%rsp)
call   1040 <fabs@plt>
movsd  (%rsp),%xmm1
divsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,(%rsp)
call   1040 <fabs@plt>
ucomisd 0xe1f(%rip),%xmm0
jbe    1210 <threshold_bins+0xe0>
movss  (%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
movss  (%r12,%rbx,1),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  0xe0a(%rip),%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%r12,%rbx,1)
jmp    1216 <threshold_bins+0xe6>
xchg   %ax,%ax
movss  (%r12,%rbx,1),%xmm0
xorps  %xmm1,%xmm1
cvtss2sd %xmm0,%xmm1
ucomisd 0xdeb(%rip),%xmm1
movss  0xdf3(%rip),%xmm0
ja     1160 <threshold_bins+0x30>
movsd  0xddd(%rip),%xmm0
ucomisd %xmm1,%xmm0
movss  0xddd(%rip),%xmm0
ja     1160 <threshold_bins+0x30>
jmp    1166 <threshold_bins+0x36>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.threshold_bins.cutoffs = [4 x float] [float 0x3FA47AE140000000, float 0x3FA47AE140000000, float 0x3FA47AE140000000, float 0x3FA47AE140000000]
@__const.threshold_bins.goal = [4 x float] [float 0x3FD3333340000000, float 0x3FD3333340000000, float 0x3FD3333340000000, float 0x3FB99999A0000000]
define void @threshold_bins(float* %0, float* %1, float* %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca float*
%7 = alloca [4 x float]
%8 = alloca [4 x float]
%9 = alloca i32
%10 = alloca float
store float* %0, float** %4
store float* %1, float** %5
store float* %2, float** %6
%11 = bitcast [4 x float]* %7 to i8*
%12 = bitcast [4 x float]* %8 to i8*
store i32 0, i32* %9
br label %13
13: ; preds = %117, %3
%14 = load i32, i32* %9
%15 = icmp slt i32 %14, 4
br i1 %15, label %16, label %120
16: ; preds = %13
%17 = load float*, float** %4
%18 = load i32, i32* %9
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds float, float* %17, i64 %19
%21 = load float, float* %20
%22 = load float*, float** %6
%23 = load i32, i32* %9
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds float, float* %22, i64 %24
%26 = load float, float* %25
%27 = call float @bin_above_threshold(float %21, float %26)
%28 = load float*, float** %4
%29 = load i32, i32* %9
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds float, float* %28, i64 %30
store float %27, float* %31
%32 = load float*, float** %4
%33 = load i32, i32* %9
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds float, float* %32, i64 %34
%36 = load float, float* %35
%37 = load float*, float** %6
%38 = load i32, i32* %9
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds float, float* %37, i64 %39
%41 = load float, float* %40
%42 = load float*, float** %5
%43 = load i32, i32* %9
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds float, float* %42, i64 %44
%46 = load float, float* %45
%47 = load i32, i32* %9
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds [4 x float], [4 x float]* %7, i64 0, i64 %48
%50 = load float, float* %49
%51 = call float @binary_act_filter(float %36, float %41, float %46, float %50)
%52 = load float*, float** %5
%53 = load i32, i32* %9
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds float, float* %52, i64 %54
store float %51, float* %55
%56 = load i32, i32* %9
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds [4 x float], [4 x float]* %8, i64 0, i64 %57
%59 = load float, float* %58
%60 = load float*, float** %5
%61 = load i32, i32* %9
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds float, float* %60, i64 %62
%64 = load float, float* %63
%65 = fsub float %59, %64
%66 = fpext float %65 to double
%67 = load float*, float** %5
%68 = load i32, i32* %9
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds float, float* %67, i64 %69
%71 = load float, float* %70
%72 = call double @fabs(float %71)
%73 = fdiv double %66, %72
%74 = fptrunc double %73 to float
store float %74, float* %10
%75 = load float, float* %10
%76 = call double @fabs(float %75)
%77 = fcmp ogt double %76, 5.000000e-02
br i1 %77, label %78, label %89
78: ; preds = %16
%79 = load float, float* %10
%80 = fpext float %79 to double
%81 = load float*, float** %6
%82 = load i32, i32* %9
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds float, float* %81, i64 %83
%85 = load float, float* %84
%86 = fpext float %85 to double
%87 = call double @llvm.fmuladd.f64(double -1.000000e-03, double %80, double %86)
%88 = fptrunc double %87 to float
store float %88, float* %84
br label %89
89: ; preds = %78, %16
%90 = load float*, float** %6
%91 = load i32, i32* %9
%92 = sext i32 %91 to i64
%93 = getelementptr inbounds float, float* %90, i64 %92
%94 = load float, float* %93
%95 = fpext float %94 to double
%96 = fcmp ogt double %95, 9.000000e-01
br i1 %96, label %97, label %102
97: ; preds = %89
%98 = load float*, float** %6
%99 = load i32, i32* %9
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds float, float* %98, i64 %100
store float 0x3FECCCCCC0000000, float* %101
br label %116
102: ; preds = %89
%103 = load float*, float** %6
%104 = load i32, i32* %9
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds float, float* %103, i64 %105
%107 = load float, float* %106
%108 = fpext float %107 to double
%109 = fcmp olt double %108, 2.000000e-02
br i1 %109, label %110, label %115
110: ; preds = %102
%111 = load float*, float** %6
%112 = load i32, i32* %9
%113 = sext i32 %112 to i64
%114 = getelementptr inbounds float, float* %111, i64 %113
store float 0x3F947AE140000000, float* %114
br label %115
115: ; preds = %110, %102
br label %116
116: ; preds = %115, %97
br label %117
117: ; preds = %116
%118 = load i32, i32* %9
%119 = add nsw i32 %118, 1
store i32 %119, i32* %9
br label %13
120: ; preds = %13
ret void
}

LLVM IR (-O2):
@__const.threshold_bins.cutoffs = [4 x float] [float 0x3FA47AE140000000, float 0x3FA47AE140000000, float 0x3FA47AE140000000, float 0x3FA47AE140000000]
@__const.threshold_bins.goal = [4 x float] [float 0x3FD3333340000000, float 0x3FD3333340000000, float 0x3FD3333340000000, float 0x3FB99999A0000000]
define void @threshold_bins(float* nocapture %0, float* nocapture %1, float* nocapture %2) {
br label %5
4: ; preds = %43
ret void
5: ; preds = %3, %43
%6 = phi i64 [ 0, %3 ], [ %44, %43 ]
%7 = getelementptr inbounds float, float* %0, i64 %6
%8 = load float, float* %7
%9 = getelementptr inbounds float, float* %2, i64 %6
%10 = load float, float* %9
%11 = tail call float @bin_above_threshold(float %8, float %10)
store float %11, float* %7
%12 = load float, float* %9
%13 = getelementptr inbounds float, float* %1, i64 %6
%14 = load float, float* %13
%15 = getelementptr inbounds [4 x float], [4 x float]* @__const.threshold_bins.cutoffs, i64 0, i64 %6
%16 = load float, float* %15
%17 = tail call float @binary_act_filter(float %11, float %12, float %14, float %16)
store float %17, float* %13
%18 = getelementptr inbounds [4 x float], [4 x float]* @__const.threshold_bins.goal, i64 0, i64 %6
%19 = load float, float* %18
%20 = fsub float %19, %17
%21 = fpext float %20 to double
%22 = tail call double @fabs(float %17)
%23 = fdiv double %21, %22
%24 = fptrunc double %23 to float
%25 = tail call double @fabs(float %24)
%26 = fcmp ogt double %25, 5.000000e-02
br i1 %26, label %29, label %27
27: ; preds = %5
%28 = load float, float* %9
br label %35
29: ; preds = %5
%30 = fpext float %24 to double
%31 = load float, float* %9
%32 = fpext float %31 to double
%33 = tail call double @llvm.fmuladd.f64(double %30, double -1.000000e-03, double %32)
%34 = fptrunc double %33 to float
store float %34, float* %9
br label %35
35: ; preds = %27, %29
%36 = phi float [ %28, %27 ], [ %34, %29 ]
%37 = fpext float %36 to double
%38 = fcmp ogt double %37, 9.000000e-01
br i1 %38, label %41, label %39
39: ; preds = %35
%40 = fcmp olt double %37, 2.000000e-02
br i1 %40, label %41, label %43
41: ; preds = %39, %35
%42 = phi float [ 0x3FECCCCCC0000000, %35 ], [ 0x3F947AE140000000, %39 ]
store float %42, float* %9
br label %43
43: ; preds = %41, %39
%44 = add nuw nsw i64 %6, 1
%45 = icmp eq i64 %44, 4
br i1 %45, label %4, label %5
}