#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_incfunc(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_min) || y > func(x_max)) {
    sarprintf_error("Value out of bounds, precision probably too low\n");
    return x_center;
  }
  if (y < y_center)
    return dichotomy_inv_incfunc(x_min, x_center, y, precision, func);
  else
    return dichotomy_inv_incfunc(x_center, x_max, y, precision, func);
}


x86 assembly (clang, -O0):
<dichotomy_inv_incfunc>:
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_incfunc+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_incfunc+0xb4>
movss  -0x10(%rbp),%xmm1
subss  -0x28(%rbp),%xmm1
movaps 0xe43(%rip),%xmm0
pand   %xmm0,%xmm1
divss  -0x10(%rbp),%xmm1
movss  -0x14(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    11e3 <dichotomy_inv_incfunc+0xc3>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12a3 <dichotomy_inv_incfunc+0x183>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x20(%rbp),%rax
movss  -0x8(%rbp),%xmm0
call   *%rax
movss  -0x2c(%rbp),%xmm1
ucomiss %xmm1,%xmm0
ja     122c <dichotomy_inv_incfunc+0x10c>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
movss  -0xc(%rbp),%xmm0
call   *%rax
movaps %xmm0,%xmm1
movss  -0x30(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1247 <dichotomy_inv_incfunc+0x127>
lea    0xde1(%rip),%rdi
call   1030 <sarprintf_error@plt>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12a3 <dichotomy_inv_incfunc+0x183>
movss  -0x10(%rbp),%xmm1
movss  -0x28(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1281 <dichotomy_inv_incfunc+0x161>
movss  -0x8(%rbp),%xmm0
movss  -0x24(%rbp),%xmm1
movss  -0x10(%rbp),%xmm2
movss  -0x14(%rbp),%xmm3
mov    -0x20(%rbp),%rdi
call   1040 <dichotomy_inv_incfunc@plt>
movss  %xmm0,-0x4(%rbp)
jmp    12a3 <dichotomy_inv_incfunc+0x183>
movss  -0x24(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
movss  -0x10(%rbp),%xmm2
movss  -0x14(%rbp),%xmm3
mov    -0x20(%rbp),%rdi
call   1040 <dichotomy_inv_incfunc@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dichotomy_inv_incfunc>:
push   %r14
push   %rbx
sub    $0x58,%rsp
movss  %xmm3,0x4(%rsp)
movaps %xmm2,0x10(%rsp)
movaps %xmm2,%xmm4
andps  0xed4(%rip),%xmm4
movaps %xmm4,0x40(%rsp)
ucomiss %xmm4,%xmm3
seta   %bl
mov    %rdi,%r14
movaps %xmm0,0x30(%rsp)
movss  %xmm1,0x8(%rsp)
addss  %xmm1,%xmm0
mulss  0xebf(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
call   *%rdi
movaps 0x10(%rsp),%xmm2
movss  0x4(%rsp),%xmm1
movaps %xmm2,%xmm3
subss  %xmm0,%xmm3
andps  0xe8f(%rip),%xmm3
jmp    11d1 <dichotomy_inv_incfunc+0xc1>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movaps %xmm2,%xmm0
cmpltss %xmm3,%xmm0
movaps 0x30(%rsp),%xmm2
andps  %xmm0,%xmm2
andnps %xmm1,%xmm0
orps   %xmm0,%xmm2
movaps %xmm2,0x30(%rsp)
movaps %xmm2,%xmm0
movss  %xmm4,0x8(%rsp)
addss  %xmm4,%xmm0
mulss  0xe60(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
call   *%r14
movaps 0x10(%rsp),%xmm2
movaps %xmm2,%xmm3
subss  %xmm0,%xmm3
andps  0xe35(%rip),%xmm3
movss  0x4(%rsp),%xmm1
ucomiss %xmm3,%xmm1
seta   %al
test   %al,%bl
jne    1248 <dichotomy_inv_incfunc+0x138>
divss  %xmm2,%xmm3
ucomiss %xmm3,%xmm1
ja     1248 <dichotomy_inv_incfunc+0x138>
movss  %xmm0,0xc(%rsp)
movaps 0x30(%rsp),%xmm0
call   *%r14
ucomiss 0x10(%rsp),%xmm0
ja     123c <dichotomy_inv_incfunc+0x12c>
movss  0x8(%rsp),%xmm0
call   *%r14
movaps 0x10(%rsp),%xmm2
ucomiss %xmm0,%xmm2
ja     123c <dichotomy_inv_incfunc+0x12c>
movss  0x4(%rsp),%xmm0
ucomiss 0x40(%rsp),%xmm0
seta   %bl
movss  0xc(%rsp),%xmm3
ucomiss %xmm2,%xmm3
movaps 0x20(%rsp),%xmm1
movaps %xmm1,%xmm4
ja     1180 <dichotomy_inv_incfunc+0x70>
movss  0x8(%rsp),%xmm4
jmp    1180 <dichotomy_inv_incfunc+0x70>
lea    0xdd1(%rip),%rdi
call   1030 <sarprintf_error@plt>
movaps 0x20(%rsp),%xmm0
add    $0x58,%rsp
pop    %rbx
pop    %r14
ret

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