#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 fabsf(float);
int /*<<< orphan*/ sarprintf_error(char *);
float dichotomy_inv_decfunc(float x_min, float x_max, float y, float precision,
                            float (*func)(float)) {
  float x_center = (x_min + x_max) / 2;
  float y_center = func(x_center);
  if ((fabsf(y) < precision && fabsf(y - y_center) < precision) ||
      fabsf((y - y_center) / y) < precision)
    return x_center;
  if (y < func(x_max) || y > func(x_min)) {
    sarprintf_error("Value out of bounds, precision probably too low\n");
    return x_center;
  }
  if (y > y_center)
    return dichotomy_inv_decfunc(x_min, x_center, y, precision, func);
  else
    return dichotomy_inv_decfunc(x_center, x_max, y, precision, func);
}


x86 assembly (clang, -O0):
<dichotomy_inv_decfunc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  %xmm2,-0x10(%rbp)
movss  %xmm3,-0x14(%rbp)
mov    %rdi,-0x20(%rbp)
movss  -0x8(%rbp),%xmm0
addss  -0xc(%rbp),%xmm0
movss  0xebe(%rip),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x20(%rbp),%rax
movss  -0x24(%rbp),%xmm0
call   *%rax
movss  %xmm0,-0x28(%rbp)
movss  -0x10(%rbp),%xmm1
movaps 0xe89(%rip),%xmm0
pand   %xmm0,%xmm1
movss  -0x14(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    11ac <dichotomy_inv_decfunc+0x8c>
movss  -0x10(%rbp),%xmm1
subss  -0x28(%rbp),%xmm1
movaps 0xe66(%rip),%xmm0
pand   %xmm0,%xmm1
movss  -0x14(%rbp),%xmm0
ucomiss %xmm1,%xmm0
ja     11d4 <dichotomy_inv_decfunc+0xb4>
movss  -0x10(%rbp),%xmm1
subss  -0x28(%rbp),%xmm1
divss  -0x10(%rbp),%xmm1
movaps 0xe3e(%rip),%xmm0
pand   %xmm0,%xmm1
movss  -0x14(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    11e3 <dichotomy_inv_decfunc+0xc3>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    129f <dichotomy_inv_decfunc+0x17f>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x20(%rbp),%rax
movss  -0xc(%rbp),%xmm0
call   *%rax
movss  -0x2c(%rbp),%xmm1
ucomiss %xmm1,%xmm0
ja     122c <dichotomy_inv_decfunc+0x10c>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
movss  -0x8(%rbp),%xmm0
call   *%rax
movaps %xmm0,%xmm1
movss  -0x30(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1247 <dichotomy_inv_decfunc+0x127>
lea    0xde1(%rip),%rdi
call   1040 <sarprintf_error@plt>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    129f <dichotomy_inv_decfunc+0x17f>
movss  -0x10(%rbp),%xmm0
ucomiss -0x28(%rbp),%xmm0
jbe    127d <dichotomy_inv_decfunc+0x15d>
movss  -0x8(%rbp),%xmm0
movss  -0x24(%rbp),%xmm1
movss  -0x10(%rbp),%xmm2
movss  -0x14(%rbp),%xmm3
mov    -0x20(%rbp),%rdi
call   1030 <dichotomy_inv_decfunc@plt>
movss  %xmm0,-0x4(%rbp)
jmp    129f <dichotomy_inv_decfunc+0x17f>
movss  -0x24(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
movss  -0x10(%rbp),%xmm2
movss  -0x14(%rbp),%xmm3
mov    -0x20(%rbp),%rdi
call   1030 <dichotomy_inv_decfunc@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dichotomy_inv_decfunc>:
push   %rbx
sub    $0x60,%rsp
mov    %rdi,%rbx
movss  %xmm3,0xc(%rsp)
movaps %xmm2,0x10(%rsp)
movaps %xmm2,%xmm3
andps  0xed3(%rip),%xmm3
movaps %xmm3,0x40(%rsp)
movaps %xmm0,0x30(%rsp)
movss  %xmm1,0x8(%rsp)
addss  %xmm1,%xmm0
mulss  0xec7(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
call   *%rdi
movaps 0xea9(%rip),%xmm4
movaps 0x10(%rsp),%xmm3
movss  0xc(%rsp),%xmm2
ucomiss 0x40(%rsp),%xmm2
movaps %xmm3,%xmm5
subss  %xmm0,%xmm5
jbe    117f <dichotomy_inv_decfunc+0x6f>
movaps %xmm5,%xmm1
andps  %xmm4,%xmm1
ucomiss %xmm1,%xmm2
ja     1269 <dichotomy_inv_decfunc+0x159>
movss  0x8(%rsp),%xmm1
cs nopw 0x0(%rax,%rax,1)
nop
divss  %xmm3,%xmm5
andps  %xmm4,%xmm5
ucomiss %xmm5,%xmm2
ja     1269 <dichotomy_inv_decfunc+0x159>
movaps %xmm0,0x50(%rsp)
movss  %xmm1,0x8(%rsp)
movaps %xmm1,%xmm0
call   *%rbx
ucomiss 0x10(%rsp),%xmm0
ja     125d <dichotomy_inv_decfunc+0x14d>
movaps 0x30(%rsp),%xmm0
call   *%rbx
movaps 0x10(%rsp),%xmm1
ucomiss %xmm0,%xmm1
ja     125d <dichotomy_inv_decfunc+0x14d>
movaps 0x50(%rsp),%xmm2
ucomiss %xmm2,%xmm1
movaps 0x20(%rsp),%xmm0
movaps %xmm0,%xmm3
ja     11e8 <dichotomy_inv_decfunc+0xd8>
movss  0x8(%rsp),%xmm3
movss  %xmm3,0x8(%rsp)
cmpltss %xmm1,%xmm2
movaps 0x30(%rsp),%xmm1
andps  %xmm2,%xmm1
andnps %xmm0,%xmm2
orps   %xmm2,%xmm1
movaps %xmm1,0x30(%rsp)
movaps %xmm1,%xmm0
addss  %xmm3,%xmm0
mulss  0xdfb(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
call   *%rbx
movss  0x8(%rsp),%xmm6
movaps 0x10(%rsp),%xmm3
movss  0xc(%rsp),%xmm2
ucomiss 0x40(%rsp),%xmm2
movaps %xmm3,%xmm5
subss  %xmm0,%xmm5
movaps %xmm6,%xmm1
movaps 0xdbd(%rip),%xmm4
jbe    1190 <dichotomy_inv_decfunc+0x80>
movaps %xmm5,%xmm1
andps  %xmm4,%xmm1
ucomiss %xmm1,%xmm2
movaps %xmm6,%xmm1
jbe    1190 <dichotomy_inv_decfunc+0x80>
jmp    1269 <dichotomy_inv_decfunc+0x159>
lea    0xdb0(%rip),%rdi
call   1030 <sarprintf_error@plt>
movaps 0x20(%rsp),%xmm0
add    $0x60,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [49 x i8] c"Value out of bounds, precision probably too low\0A\00"
define float @dichotomy_inv_decfunc(float %0, float %1, float %2, float %3, float (float)* %4) {
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca float (float)*
%12 = alloca float
%13 = alloca float
store float %0, float* %7
store float %1, float* %8
store float %2, float* %9
store float %3, float* %10
store float (float)* %4, float (float)** %11
%14 = load float, float* %7
%15 = load float, float* %8
%16 = fadd float %14, %15
%17 = fdiv float %16, 2.000000e+00
store float %17, float* %12
%18 = load float (float)*, float (float)** %11
%19 = load float, float* %12
%20 = call float %18(float %19)
store float %20, float* %13
%21 = load float, float* %9
%22 = call float @llvm.fabs.f32(float %21)
%23 = load float, float* %10
%24 = fcmp olt float %22, %23
br i1 %24, label %25, label %32
25: ; preds = %5
%26 = load float, float* %9
%27 = load float, float* %13
%28 = fsub float %26, %27
%29 = call float @llvm.fabs.f32(float %28)
%30 = load float, float* %10
%31 = fcmp olt float %29, %30
br i1 %31, label %41, label %32
32: ; preds = %25, %5
%33 = load float, float* %9
%34 = load float, float* %13
%35 = fsub float %33, %34
%36 = load float, float* %9
%37 = fdiv float %35, %36
%38 = call float @llvm.fabs.f32(float %37)
%39 = load float, float* %10
%40 = fcmp olt float %38, %39
br i1 %40, label %41, label %43
41: ; preds = %32, %25
%42 = load float, float* %12
store float %42, float* %6
br label %76
43: ; preds = %32
%44 = load float, float* %9
%45 = load float (float)*, float (float)** %11
%46 = load float, float* %8
%47 = call float %45(float %46)
%48 = fcmp olt float %44, %47
br i1 %48, label %55, label %49
49: ; preds = %43
%50 = load float, float* %9
%51 = load float (float)*, float (float)** %11
%52 = load float, float* %7
%53 = call float %51(float %52)
%54 = fcmp ogt float %50, %53
br i1 %54, label %55, label %58
55: ; preds = %49, %43
%56 = call i32 @sarprintf_error(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0))
%57 = load float, float* %12
store float %57, float* %6
br label %76
58: ; preds = %49
%59 = load float, float* %9
%60 = load float, float* %13
%61 = fcmp ogt float %59, %60
br i1 %61, label %62, label %69
62: ; preds = %58
%63 = load float, float* %7
%64 = load float, float* %12
%65 = load float, float* %9
%66 = load float, float* %10
%67 = load float (float)*, float (float)** %11
%68 = call float @dichotomy_inv_decfunc(float %63, float %64, float %65, float %66, float (float)* %67)
store float %68, float* %6
br label %76
69: ; preds = %58
%70 = load float, float* %12
%71 = load float, float* %8
%72 = load float, float* %9
%73 = load float, float* %10
%74 = load float (float)*, float (float)** %11
%75 = call float @dichotomy_inv_decfunc(float %70, float %71, float %72, float %73, float (float)* %74)
store float %75, float* %6
br label %76
76: ; preds = %69, %62, %55, %41
%77 = load float, float* %6
ret float %77
}

LLVM IR (-O2):
@.str = [49 x i8] c"Value out of bounds, precision probably too low\0A\00"
define float @dichotomy_inv_decfunc(float %0, float %1, float %2, float %3, float (float)* %4) {
%6 = tail call float @llvm.fabs.f32(float %2)
%7 = fcmp olt float %6, %3
%8 = fadd float %0, %1
%9 = fmul float %8, 5.000000e-01
%10 = tail call float %4(float %9)
%11 = fsub float %2, %10
%12 = tail call float @llvm.fabs.f32(float %11)
%13 = fcmp olt float %12, %3
%14 = select i1 %7, i1 %13, i1 false
br i1 %14, label %43, label %15
15: ; preds = %5, %32
%16 = phi float [ %39, %32 ], [ %11, %5 ]
%17 = phi float [ %38, %32 ], [ %10, %5 ]
%18 = phi float [ %37, %32 ], [ %9, %5 ]
%19 = phi float [ %35, %32 ], [ %1, %5 ]
%20 = phi float [ %34, %32 ], [ %0, %5 ]
%21 = fdiv float %16, %2
%22 = tail call float @llvm.fabs.f32(float %21)
%23 = fcmp olt float %22, %3
br i1 %23, label %43, label %24
24: ; preds = %15
%25 = tail call float %4(float %19)
%26 = fcmp ogt float %25, %2
br i1 %26, label %30, label %27
27: ; preds = %24
%28 = tail call float %4(float %20)
%29 = fcmp olt float %28, %2
br i1 %29, label %30, label %32
30: ; preds = %27, %24
%31 = tail call i32 @sarprintf_error(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0))
br label %43
32: ; preds = %27
%33 = fcmp olt float %17, %2
%34 = select i1 %33, float %20, float %18
%35 = select i1 %33, float %18, float %19
%36 = fadd float %34, %35
%37 = fmul float %36, 5.000000e-01
%38 = tail call float %4(float %37)
%39 = fsub float %2, %38
%40 = tail call float @llvm.fabs.f32(float %39)
%41 = fcmp olt float %40, %3
%42 = select i1 %7, i1 %41, i1 false
br i1 %42, label %43, label %15
43: ; preds = %32, %15, %5, %30
%44 = phi float [ %18, %30 ], [ %9, %5 ], [ %18, %15 ], [ %37, %32 ]
ret float %44
}