#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 BSAmericanApprox(int, double, double, double, double, double, double);
int /*<<< orphan*/ assert(int);
double fabs(double);
extern double BSbisection(int fCall, double S, double X, double T, double r,
                          double b, double price) {
  double vLow = 0.0000001;
  double vHigh = 100.99999, cLow, cHigh;
  double epsilon = 0.000001;
  double val, diff, vi = 0.0;
  int counter = 0;
  for (;;) {
    cLow = BSAmericanApprox(fCall, S, X, T, r, b, vLow);
    cHigh = BSAmericanApprox(fCall, S, X, T, r, b, vHigh);
    if (price < cLow)
      return 0.0;
    else if (price > cHigh)
      return 100.99999;
    vi = vLow + (price - cLow) * (vHigh - vLow) / (cHigh - cLow);
    if (vi < 0.0000001)
      vi = 0.0000001;
    else if (vi > 100.99999)
      vi = 100.99999;
    assert(((vi) == (vi)) && (vi) >= 0.0000001 && vi <= 100.99999);
    val = BSAmericanApprox(fCall, S, X, T, r, b, vi);
    diff = price - val;
    if (fabs(diff) <= epsilon)
      break;
    else if (val < price)
      vLow = vi;
    else
      vHigh = vi;
    if (counter++ >= 100)
      return 0;
  }
  return vi;
}


x86 assembly (clang, -O0):
<BSbisection>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %edi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
movsd  %xmm2,-0x28(%rbp)
movsd  %xmm3,-0x30(%rbp)
movsd  %xmm4,-0x38(%rbp)
movsd  %xmm5,-0x40(%rbp)
movsd  0xebc(%rip),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0xea7(%rip),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0xe92(%rip),%xmm0
movsd  %xmm0,-0x68(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x80(%rbp)
movl   $0x0,-0x84(%rbp)
mov    -0xc(%rbp),%edi
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm3
movsd  -0x38(%rbp),%xmm4
movsd  -0x48(%rbp),%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  %xmm0,-0x58(%rbp)
mov    -0xc(%rbp),%edi
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm3
movsd  -0x38(%rbp),%xmm4
movsd  -0x50(%rbp),%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  %xmm0,-0x60(%rbp)
movsd  -0x40(%rbp),%xmm1
movsd  -0x58(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11fc <BSbisection+0xdc>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13ce <BSbisection+0x2ae>
movsd  -0x40(%rbp),%xmm0
ucomisd -0x60(%rbp),%xmm0
jbe    121e <BSbisection+0xfe>
movsd  0xdf4(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13ce <BSbisection+0x2ae>
jmp    1223 <BSbisection+0x103>
movsd  -0x48(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
subsd  -0x58(%rbp),%xmm1
movsd  -0x50(%rbp),%xmm2
subsd  -0x48(%rbp),%xmm2
mulsd  %xmm2,%xmm1
movsd  -0x60(%rbp),%xmm2
subsd  -0x58(%rbp),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  0xdb1(%rip),%xmm0
ucomisd -0x80(%rbp),%xmm0
jbe    127c <BSbisection+0x15c>
movsd  0xd9e(%rip),%xmm0
movsd  %xmm0,-0x80(%rbp)
jmp    12a5 <BSbisection+0x185>
movsd  -0x80(%rbp),%xmm0
movsd  0xd7f(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12a0 <BSbisection+0x180>
movsd  0xd6d(%rip),%xmm0
movsd  %xmm0,-0x80(%rbp)
jmp    12a5 <BSbisection+0x185>
movsd  -0x80(%rbp),%xmm0
xor    %eax,%eax
ucomisd -0x80(%rbp),%xmm0
mov    %al,-0x85(%rbp)
jne    12f8 <BSbisection+0x1d8>
jp     12f8 <BSbisection+0x1d8>
movsd  -0x80(%rbp),%xmm0
xor    %eax,%eax
movsd  0xd3e(%rip),%xmm1
ucomisd %xmm1,%xmm0
mov    %al,-0x85(%rbp)
jb     12f8 <BSbisection+0x1d8>
movsd  0xd1e(%rip),%xmm0
ucomisd -0x80(%rbp),%xmm0
setae  %al
mov    %al,-0x85(%rbp)
mov    -0x85(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
mov    -0xc(%rbp),%edi
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm3
movsd  -0x38(%rbp),%xmm4
movsd  -0x80(%rbp),%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
subsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm1
movaps 0xcd2(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  -0x68(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     1366 <BSbisection+0x246>
jmp    13c4 <BSbisection+0x2a4>
movsd  -0x70(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1389 <BSbisection+0x269>
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    1393 <BSbisection+0x273>
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
jmp    1398 <BSbisection+0x278>
mov    -0x84(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x84(%rbp)
cmp    $0x64,%eax
jl     13bf <BSbisection+0x29f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    13ce <BSbisection+0x2ae>
jmp    1185 <BSbisection+0x65>
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<BSbisection>:
push   %rbp
push   %rbx
sub    $0x68,%rsp
movsd  %xmm4,0x28(%rsp)
movsd  %xmm3,0x20(%rsp)
movsd  %xmm2,0x18(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm0,0x8(%rsp)
mov    %edi,%ebx
movsd  0xeb2(%rip),%xmm6
movsd  0xeb2(%rip),%xmm2
mov    $0x65,%ebp
movsd  %xmm5,0x40(%rsp)
jmp    1190 <BSbisection+0x70>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
cmpltsd %xmm5,%xmm0
movapd 0x50(%rsp),%xmm2
andpd  %xmm0,%xmm2
andnpd %xmm3,%xmm0
orpd   %xmm0,%xmm2
add    $0xffffffff,%ebp
je     131b <BSbisection+0x1fb>
movapd %xmm2,0x50(%rsp)
mov    %ebx,%edi
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x18(%rsp),%xmm2
movsd  0x20(%rsp),%xmm3
movsd  0x28(%rsp),%xmm4
movsd  %xmm6,0x48(%rsp)
movapd %xmm6,%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  %xmm0,0x30(%rsp)
mov    %ebx,%edi
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x18(%rsp),%xmm2
movsd  0x20(%rsp),%xmm3
movsd  0x28(%rsp),%xmm4
movaps 0x50(%rsp),%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  0x30(%rsp),%xmm4
movsd  0x40(%rsp),%xmm2
ucomisd %xmm2,%xmm4
ja     1301 <BSbisection+0x1e1>
ucomisd %xmm0,%xmm2
ja     1307 <BSbisection+0x1e7>
xorps  %xmm1,%xmm1
movsd  %xmm1,(%rsp)
subsd  %xmm4,%xmm2
movapd 0x50(%rsp),%xmm1
movsd  0x48(%rsp),%xmm3
subsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm1
subsd  %xmm4,%xmm0
divsd  %xmm0,%xmm1
addsd  %xmm3,%xmm1
movsd  0xdb7(%rip),%xmm0
ucomisd %xmm1,%xmm0
movapd %xmm0,%xmm2
movsd  0xdaf(%rip),%xmm0
ja     1269 <BSbisection+0x149>
ucomisd %xmm0,%xmm1
movapd %xmm1,%xmm2
jbe    1269 <BSbisection+0x149>
movapd %xmm0,%xmm2
movapd %xmm2,0x30(%rsp)
ucomisd %xmm2,%xmm2
setnp  %al
ucomisd 0xd82(%rip),%xmm2
setae  %cl
ucomisd %xmm2,%xmm0
setae  %dl
and    %al,%dl
and    %cl,%dl
movzbl %dl,%edi
call   1030 <assert@plt>
mov    %ebx,%edi
movsd  0x8(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x18(%rsp),%xmm2
movsd  0x20(%rsp),%xmm3
movsd  0x28(%rsp),%xmm4
movaps 0x30(%rsp),%xmm5
call   1040 <BSAmericanApprox@plt>
movsd  0x40(%rsp),%xmm5
movapd %xmm5,%xmm1
subsd  %xmm0,%xmm1
andpd  0xd4c(%rip),%xmm1
movsd  0xd34(%rip),%xmm2
ucomisd %xmm1,%xmm2
jae    1311 <BSbisection+0x1f1>
ucomisd %xmm0,%xmm5
movapd 0x30(%rsp),%xmm3
movapd %xmm3,%xmm6
ja     1170 <BSbisection+0x50>
movsd  0x48(%rsp),%xmm6
jmp    1170 <BSbisection+0x50>
xorpd  %xmm0,%xmm0
jmp    1316 <BSbisection+0x1f6>
movsd  0xcf9(%rip),%xmm0
jmp    1316 <BSbisection+0x1f6>
movaps 0x30(%rsp),%xmm0
movsd  %xmm0,(%rsp)
movsd  (%rsp),%xmm0
add    $0x68,%rsp
pop    %rbx
pop    %rbp
ret

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

LLVM IR (-O2):
define double @BSbisection(i32 %0, double %1, double %2, double %3, double %4, double %5, double %6) {
br label %8
8: ; preds = %41, %7
%9 = phi double [ 0x40593FFFD60E94EE, %7 ], [ %43, %41 ]
%10 = phi double [ 0x3E7AD7F29ABCAF48, %7 ], [ %44, %41 ]
%11 = phi i32 [ 0, %7 ], [ %45, %41 ]
%12 = tail call double @BSAmericanApprox(i32 %0, double %1, double %2, double %3, double %4, double %5, double %10)
%13 = tail call double @BSAmericanApprox(i32 %0, double %1, double %2, double %3, double %4, double %5, double %9)
%14 = fcmp ogt double %12, %6
br i1 %14, label %47, label %15
15: ; preds = %8
%16 = fcmp olt double %13, %6
br i1 %16, label %47, label %17
17: ; preds = %15
%18 = fsub double %6, %12
%19 = fsub double %9, %10
%20 = fmul double %19, %18
%21 = fsub double %13, %12
%22 = fdiv double %20, %21
%23 = fadd double %10, %22
%24 = fcmp olt double %23, 0x3E7AD7F29ABCAF48
br i1 %24, label %28, label %25
25: ; preds = %17
%26 = fcmp ogt double %23, 0x40593FFFD60E94EE
br i1 %26, label %27, label %28
27: ; preds = %25
br label %28
28: ; preds = %17, %25, %27
%29 = phi double [ 0x40593FFFD60E94EE, %27 ], [ %23, %25 ], [ 0x3E7AD7F29ABCAF48, %17 ]
%30 = fcmp ord double %29, 0.000000e+00
%31 = fcmp oge double %29, 0x3E7AD7F29ABCAF48
%32 = and i1 %30, %31
%33 = fcmp ole double %29, 0x40593FFFD60E94EE
%34 = and i1 %33, %32
%35 = zext i1 %34 to i32
%36 = tail call i32 @assert(i32 %35)
%37 = tail call double @BSAmericanApprox(i32 %0, double %1, double %2, double %3, double %4, double %5, double %29)
%38 = fsub double %6, %37
%39 = tail call double @llvm.fabs.f64(double %38)
%40 = fcmp ugt double %39, 0x3EB0C6F7A0B5ED8D
br i1 %40, label %41, label %47
41: ; preds = %28
%42 = fcmp olt double %37, %6
%43 = select i1 %42, double %9, double %29
%44 = select i1 %42, double %29, double %10
%45 = add nuw nsw i32 %11, 1
%46 = icmp eq i32 %45, 101
br i1 %46, label %47, label %8
47: ; preds = %28, %41, %15, %8
%48 = phi double [ 0.000000e+00, %8 ], [ 0x40593FFFD60E94EE, %15 ], [ 0.000000e+00, %41 ], [ %29, %28 ]
ret double %48
}