#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 */
struct pumas_physics {
  int dummy;
};

/* Variables and functions */
double fabs(double);
double stub1(struct pumas_physics const *, double, void *);
double stub2(struct pumas_physics const *, double const, void *);
double stub3(struct pumas_physics const *, double const, void *);
int math_find_minimum_bisection(double (*f)(const struct pumas_physics *physics,
                                            double x, void *params),
                                const struct pumas_physics *physics, double xa,
                                double xb, double xc, const double *fb_p,
                                double tol, int max_iter, void *params,
                                double *xopt, double *fopt) {
  double fb;
  if (fb_p == NULL)
    fb = (*f)(physics, xb, params);
  else
    fb = *fb_p;
  tol *= fabs(xc - xa);
  int i = 0;
  while ((xc - xa > tol) && (i < max_iter)) {
    if (xb - xa > xc - xb) {
      const double x = 0.5 * (xa + xb);
      const double fi = (*f)(physics, x, params);
      if (fi < fb) {
        xc = xb;
        xb = x;
        fb = fi;
      } else {
        xa = x;
      }
    } else {
      const double x = 0.5 * (xb + xc);
      const double fi = (*f)(physics, x, params);
      if (fi < fb) {
        xa = xb;
        xb = x;
        fb = fi;
      } else {
        xc = x;
      }
    }
    i++;
  }
  if (xopt != NULL)
    *xopt = xb;
  if (fopt != NULL)
    *fopt = fb;
  return (i <= max_iter) ? i : -1;
}


x86 assembly (clang, -O0):
<math_find_minimum_bisection>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  %xmm2,-0x28(%rbp)
mov    %rdx,-0x30(%rbp)
movsd  %xmm3,-0x38(%rbp)
mov    %ecx,-0x3c(%rbp)
mov    %r8,-0x48(%rbp)
mov    %r9,-0x50(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    1162 <math_find_minimum_bisection+0x62>
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdi
movsd  -0x20(%rbp),%xmm0
mov    -0x48(%rbp),%rsi
call   *%rax
movsd  %xmm0,-0x58(%rbp)
jmp    116f <math_find_minimum_bisection+0x6f>
mov    -0x30(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movaps 0xe80(%rip),%xmm1
pand   %xmm1,%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movl   $0x0,-0x5c(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
xor    %eax,%eax
ucomisd -0x38(%rbp),%xmm0
mov    %al,-0x81(%rbp)
jbe    11c1 <math_find_minimum_bisection+0xc1>
mov    -0x5c(%rbp),%eax
cmp    -0x3c(%rbp),%eax
setl   %al
mov    %al,-0x81(%rbp)
mov    -0x81(%rbp),%al
test   $0x1,%al
jne    11d4 <math_find_minimum_bisection+0xd4>
jmp    12f2 <math_find_minimum_bisection+0x1f2>
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
subsd  -0x20(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    126b <math_find_minimum_bisection+0x16b>
movsd  -0x18(%rbp),%xmm1
addsd  -0x20(%rbp),%xmm1
movsd  0xe0c(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdi
movsd  -0x68(%rbp),%xmm0
mov    -0x48(%rbp),%rsi
call   *%rax
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm1
movsd  -0x58(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    125c <math_find_minimum_bisection+0x15c>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    1266 <math_find_minimum_bisection+0x166>
movsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    12e4 <math_find_minimum_bisection+0x1e4>
movsd  -0x20(%rbp),%xmm1
addsd  -0x28(%rbp),%xmm1
movsd  0xd93(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rdi
movsd  -0x78(%rbp),%xmm0
mov    -0x48(%rbp),%rsi
call   *%rax
movsd  %xmm0,-0x80(%rbp)
movsd  -0x80(%rbp),%xmm1
movsd  -0x58(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    12d5 <math_find_minimum_bisection+0x1d5>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    12df <math_find_minimum_bisection+0x1df>
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    12e4 <math_find_minimum_bisection+0x1e4>
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    1195 <math_find_minimum_bisection+0x95>
cmpq   $0x0,-0x50(%rbp)
je     130a <math_find_minimum_bisection+0x20a>
movsd  -0x20(%rbp),%xmm0
mov    -0x50(%rbp),%rax
movsd  %xmm0,(%rax)
cmpq   $0x0,0x10(%rbp)
je     1322 <math_find_minimum_bisection+0x222>
movsd  -0x58(%rbp),%xmm0
mov    0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x5c(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jg     133c <math_find_minimum_bisection+0x23c>
mov    -0x5c(%rbp),%eax
mov    %eax,-0x88(%rbp)
jmp    134c <math_find_minimum_bisection+0x24c>
mov    $0xffffffff,%eax
mov    %eax,-0x88(%rbp)
jmp    134c <math_find_minimum_bisection+0x24c>
mov    -0x88(%rbp),%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<math_find_minimum_bisection>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x58,%rsp
mov    %r9,%r14
mov    %r8,%r12
mov    %ecx,%r15d
movapd %xmm0,%xmm5
mov    %rsi,%r13
mov    %rdi,%rbx
test   %rdx,%rdx
je     112c <math_find_minimum_bisection+0x2c>
movsd  (%rdx),%xmm6
jmp    1169 <math_find_minimum_bisection+0x69>
mov    %r13,%rdi
movapd %xmm1,%xmm0
mov    %r12,%rsi
movapd %xmm1,0x10(%rsp)
movsd  %xmm5,(%rsp)
movaps %xmm2,0x30(%rsp)
movsd  %xmm3,0x8(%rsp)
call   *%rbx
movsd  0x8(%rsp),%xmm3
movapd 0x30(%rsp),%xmm2
movsd  (%rsp),%xmm5
movapd 0x10(%rsp),%xmm1
movapd %xmm0,%xmm6
movapd %xmm2,%xmm0
subsd  %xmm5,%xmm0
movapd 0xe87(%rip),%xmm4
andpd  %xmm0,%xmm4
mulsd  %xmm3,%xmm4
xor    %ebp,%ebp
movapd %xmm4,0x40(%rsp)
ucomisd %xmm4,%xmm0
jbe    12cf <math_find_minimum_bisection+0x1cf>
test   %r15d,%r15d
jle    12cf <math_find_minimum_bisection+0x1cf>
xor    %ebp,%ebp
xchg   %ax,%ax
movsd  %xmm6,0x8(%rsp)
movapd %xmm1,%xmm0
subsd  %xmm5,%xmm0
movapd %xmm2,%xmm3
subsd  %xmm1,%xmm3
ucomisd %xmm3,%xmm0
movapd %xmm1,0x10(%rsp)
movsd  %xmm5,(%rsp)
movapd %xmm2,0x30(%rsp)
jbe    1240 <math_find_minimum_bisection+0x140>
movapd %xmm1,%xmm0
addsd  %xmm5,%xmm0
mulsd  0xe33(%rip),%xmm0
mov    %r13,%rdi
movapd %xmm0,0x20(%rsp)
mov    %r12,%rsi
call   *%rbx
movapd 0x10(%rsp),%xmm3
movapd %xmm0,%xmm1
movsd  0x8(%rsp),%xmm4
ucomisd %xmm0,%xmm4
movapd %xmm3,%xmm0
ja     120b <math_find_minimum_bisection+0x10b>
movapd 0x30(%rsp),%xmm0
movsd  (%rsp),%xmm5
movapd 0x20(%rsp),%xmm6
ja     121c <math_find_minimum_bisection+0x11c>
movapd %xmm6,%xmm5
movapd %xmm1,%xmm2
minsd  %xmm4,%xmm2
cmpltsd %xmm4,%xmm1
andpd  %xmm1,%xmm6
andnpd %xmm3,%xmm1
orpd   %xmm6,%xmm1
movapd %xmm2,%xmm6
jmp    12af <math_find_minimum_bisection+0x1af>
nopl   0x0(%rax,%rax,1)
movapd %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  0xdc0(%rip),%xmm0
mov    %r13,%rdi
movapd %xmm0,0x20(%rsp)
mov    %r12,%rsi
call   *%rbx
movsd  0x8(%rsp),%xmm2
ucomisd %xmm0,%xmm2
ja     1280 <math_find_minimum_bisection+0x180>
movapd 0x10(%rsp),%xmm1
movsd  (%rsp),%xmm5
movapd 0x20(%rsp),%xmm4
jmp    1290 <math_find_minimum_bisection+0x190>
nopl   (%rax)
movapd 0x10(%rsp),%xmm5
movapd 0x20(%rsp),%xmm4
movapd %xmm4,%xmm1
movapd %xmm0,%xmm6
minsd  %xmm2,%xmm6
cmpltsd %xmm2,%xmm0
movapd %xmm0,%xmm2
andnpd %xmm4,%xmm2
andpd  0x30(%rsp),%xmm0
orpd   %xmm2,%xmm0
add    $0x1,%ebp
movapd %xmm0,%xmm2
subsd  %xmm5,%xmm2
ucomisd 0x40(%rsp),%xmm2
jbe    12cf <math_find_minimum_bisection+0x1cf>
movapd %xmm0,%xmm2
cmp    %r15d,%ebp
jl     11a0 <math_find_minimum_bisection+0xa0>
mov    0x90(%rsp),%rax
test   %r14,%r14
je     12e1 <math_find_minimum_bisection+0x1e1>
movsd  %xmm1,(%r14)
test   %rax,%rax
je     12ea <math_find_minimum_bisection+0x1ea>
movsd  %xmm6,(%rax)
cmp    %r15d,%ebp
mov    $0xffffffff,%eax
cmovle %ebp,%eax
add    $0x58,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.pumas_physics = type { i32 }
define i32 @math_find_minimum_bisection(double (%struct.pumas_physics*, double, i8*)* %0, %struct.pumas_physics* %1, double %2, double %3, double %4, double* %5, double %6, i32 %7, i8* %8, double* %9, double* %10) {
%12 = alloca double (%struct.pumas_physics*, double, i8*)*
%13 = alloca %struct.pumas_physics*
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double*
%18 = alloca double
%19 = alloca i32
%20 = alloca i8*
%21 = alloca double*
%22 = alloca double*
%23 = alloca double
%24 = alloca i32
%25 = alloca double
%26 = alloca double
%27 = alloca double
%28 = alloca double
store double (%struct.pumas_physics*, double, i8*)* %0, double (%struct.pumas_physics*, double, i8*)** %12
store %struct.pumas_physics* %1, %struct.pumas_physics** %13
store double %2, double* %14
store double %3, double* %15
store double %4, double* %16
store double* %5, double** %17
store double %6, double* %18
store i32 %7, i32* %19
store i8* %8, i8** %20
store double* %9, double** %21
store double* %10, double** %22
%29 = load double*, double** %17
%30 = icmp eq double* %29, null
br i1 %30, label %31, label %37
31: ; preds = %11
%32 = load double (%struct.pumas_physics*, double, i8*)*, double (%struct.pumas_physics*, double, i8*)** %12
%33 = load %struct.pumas_physics*, %struct.pumas_physics** %13
%34 = load double, double* %15
%35 = load i8*, i8** %20
%36 = call double %32(%struct.pumas_physics* %33, double %34, i8* %35)
store double %36, double* %23
br label %40
37: ; preds = %11
%38 = load double*, double** %17
%39 = load double, double* %38
store double %39, double* %23
br label %40
40: ; preds = %37, %31
%41 = load double, double* %16
%42 = load double, double* %14
%43 = fsub double %41, %42
%44 = call double @llvm.fabs.f64(double %43)
%45 = load double, double* %18
%46 = fmul double %45, %44
store double %46, double* %18
store i32 0, i32* %24
br label %47
47: ; preds = %107, %40
%48 = load double, double* %16
%49 = load double, double* %14
%50 = fsub double %48, %49
%51 = load double, double* %18
%52 = fcmp ogt double %50, %51
br i1 %52, label %53, label %57
53: ; preds = %47
%54 = load i32, i32* %24
%55 = load i32, i32* %19
%56 = icmp slt i32 %54, %55
br label %57
57: ; preds = %53, %47
%58 = phi i1 [ false, %47 ], [ %56, %53 ]
br i1 %58, label %59, label %110
59: ; preds = %57
%60 = load double, double* %15
%61 = load double, double* %14
%62 = fsub double %60, %61
%63 = load double, double* %16
%64 = load double, double* %15
%65 = fsub double %63, %64
%66 = fcmp ogt double %62, %65
br i1 %66, label %67, label %87
67: ; preds = %59
%68 = load double, double* %14
%69 = load double, double* %15
%70 = fadd double %68, %69
%71 = fmul double 5.000000e-01, %70
store double %71, double* %25
%72 = load double (%struct.pumas_physics*, double, i8*)*, double (%struct.pumas_physics*, double, i8*)** %12
%73 = load %struct.pumas_physics*, %struct.pumas_physics** %13
%74 = load double, double* %25
%75 = load i8*, i8** %20
%76 = call double %72(%struct.pumas_physics* %73, double %74, i8* %75)
store double %76, double* %26
%77 = load double, double* %26
%78 = load double, double* %23
%79 = fcmp olt double %77, %78
br i1 %79, label %80, label %84
80: ; preds = %67
%81 = load double, double* %15
store double %81, double* %16
%82 = load double, double* %25
store double %82, double* %15
%83 = load double, double* %26
store double %83, double* %23
br label %86
84: ; preds = %67
%85 = load double, double* %25
store double %85, double* %14
br label %86
86: ; preds = %84, %80
br label %107
87: ; preds = %59
%88 = load double, double* %15
%89 = load double, double* %16
%90 = fadd double %88, %89
%91 = fmul double 5.000000e-01, %90
store double %91, double* %27
%92 = load double (%struct.pumas_physics*, double, i8*)*, double (%struct.pumas_physics*, double, i8*)** %12
%93 = load %struct.pumas_physics*, %struct.pumas_physics** %13
%94 = load double, double* %27
%95 = load i8*, i8** %20
%96 = call double %92(%struct.pumas_physics* %93, double %94, i8* %95)
store double %96, double* %28
%97 = load double, double* %28
%98 = load double, double* %23
%99 = fcmp olt double %97, %98
br i1 %99, label %100, label %104
100: ; preds = %87
%101 = load double, double* %15
store double %101, double* %14
%102 = load double, double* %27
store double %102, double* %15
%103 = load double, double* %28
store double %103, double* %23
br label %106
104: ; preds = %87
%105 = load double, double* %27
store double %105, double* %16
br label %106
106: ; preds = %104, %100
br label %107
107: ; preds = %106, %86
%108 = load i32, i32* %24
%109 = add nsw i32 %108, 1
store i32 %109, i32* %24
br label %47
110: ; preds = %57
%111 = load double*, double** %21
%112 = icmp ne double* %111, null
br i1 %112, label %113, label %116
113: ; preds = %110
%114 = load double, double* %15
%115 = load double*, double** %21
store double %114, double* %115
br label %116
116: ; preds = %113, %110
%117 = load double*, double** %22
%118 = icmp ne double* %117, null
br i1 %118, label %119, label %122
119: ; preds = %116
%120 = load double, double* %23
%121 = load double*, double** %22
store double %120, double* %121
br label %122
122: ; preds = %119, %116
%123 = load i32, i32* %24
%124 = load i32, i32* %19
%125 = icmp sle i32 %123, %124
br i1 %125, label %126, label %128
126: ; preds = %122
%127 = load i32, i32* %24
br label %129
128: ; preds = %122
br label %129
129: ; preds = %128, %126
%130 = phi i32 [ %127, %126 ], [ -1, %128 ]
ret i32 %130
}

LLVM IR (-O2):
%struct.pumas_physics = type { i32 }
define i32 @math_find_minimum_bisection(double (%struct.pumas_physics*, double, i8*)* nocapture %0, %struct.pumas_physics* %1, double %2, double %3, double %4, double* %5, double %6, i32 %7, i8* %8, double* writeonly %9, double* writeonly %10) {
%12 = icmp eq double* %5, null
br i1 %12, label %13, label %15
13: ; preds = %11
%14 = tail call double %0(%struct.pumas_physics* %1, double %3, i8* %8)
br label %17
15: ; preds = %11
%16 = load double, double* %5
br label %17
17: ; preds = %15, %13
%18 = phi double [ %14, %13 ], [ %16, %15 ]
%19 = fsub double %4, %2
%20 = tail call double @llvm.fabs.f64(double %19)
%21 = fmul double %20, %6
%22 = fcmp ogt double %19, %21
%23 = icmp sgt i32 %7, 0
%24 = and i1 %22, %23
br i1 %24, label %25, label %62
25: ; preds = %17, %52
%26 = phi double [ %56, %52 ], [ %2, %17 ]
%27 = phi double [ %55, %52 ], [ %3, %17 ]
%28 = phi double [ %54, %52 ], [ %4, %17 ]
%29 = phi i32 [ %57, %52 ], [ 0, %17 ]
%30 = phi double [ %53, %52 ], [ %18, %17 ]
%31 = fsub double %27, %26
%32 = fsub double %28, %27
%33 = fcmp ogt double %31, %32
br i1 %33, label %34, label %43
34: ; preds = %25
%35 = fadd double %27, %26
%36 = fmul double %35, 5.000000e-01
%37 = tail call double %0(%struct.pumas_physics* %1, double %36, i8* %8)
%38 = fcmp olt double %37, %30
%39 = select i1 %38, double %37, double %30
%40 = select i1 %38, double %27, double %28
%41 = select i1 %38, double %36, double %27
%42 = select i1 %38, double %26, double %36
br label %52
43: ; preds = %25
%44 = fadd double %28, %27
%45 = fmul double %44, 5.000000e-01
%46 = tail call double %0(%struct.pumas_physics* %1, double %45, i8* %8)
%47 = fcmp olt double %46, %30
%48 = select i1 %47, double %46, double %30
%49 = select i1 %47, double %28, double %45
%50 = select i1 %47, double %45, double %27
%51 = select i1 %47, double %27, double %26
br label %52
52: ; preds = %43, %34
%53 = phi double [ %39, %34 ], [ %48, %43 ]
%54 = phi double [ %40, %34 ], [ %49, %43 ]
%55 = phi double [ %41, %34 ], [ %50, %43 ]
%56 = phi double [ %42, %34 ], [ %51, %43 ]
%57 = add nuw nsw i32 %29, 1
%58 = fsub double %54, %56
%59 = fcmp ogt double %58, %21
%60 = icmp slt i32 %57, %7
%61 = select i1 %59, i1 %60, i1 false
br i1 %61, label %25, label %62
62: ; preds = %52, %17
%63 = phi double [ %18, %17 ], [ %53, %52 ]
%64 = phi i32 [ 0, %17 ], [ %57, %52 ]
%65 = phi double [ %3, %17 ], [ %55, %52 ]
%66 = icmp eq double* %9, null
br i1 %66, label %68, label %67
67: ; preds = %62
store double %65, double* %9
br label %68
68: ; preds = %67, %62
%69 = icmp eq double* %10, null
br i1 %69, label %71, label %70
70: ; preds = %68
store double %63, double* %10
br label %71
71: ; preds = %70, %68
%72 = icmp sgt i32 %64, %7
%73 = select i1 %72, i32 -1, i32 %64
ret i32 %73
}