#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 exp(double);
double rq_pricing_blackscholes(short, double, double, double, double, double,
                               double, double);
double rq_pricing_bond_opt(short call, double B, double X, double r_dom,
                           double sigma, double tau_e, double tau_d,
                           short num_coupons, double *coupon_times,
                           double *coupon_amounts, double *coupon_r) {
  short i;
  for (i = 0; i < num_coupons; i++)
    if (coupon_times[i] <= tau_e)
      B -= coupon_amounts[i] * exp(-coupon_r[i] * coupon_times[i]);
  return rq_pricing_blackscholes(call, B, X, r_dom, 0.0, sigma, tau_e, tau_d);
}


x86 assembly (clang, -O0):
<rq_pricing_bond_opt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %si,%ax
mov    %di,%si
mov    %si,-0x2(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  %xmm5,-0x38(%rbp)
mov    %ax,-0x3a(%rbp)
mov    %rdx,-0x48(%rbp)
mov    %rcx,-0x50(%rbp)
mov    %r8,-0x58(%rbp)
movw   $0x0,-0x5a(%rbp)
movswl -0x5a(%rbp),%eax
movswl -0x3a(%rbp),%ecx
cmp    %ecx,%eax
jge    1225 <rq_pricing_bond_opt+0x105>
mov    -0x48(%rbp),%rax
movswq -0x5a(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x30(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     120f <rq_pricing_bond_opt+0xef>
mov    -0x50(%rbp),%rax
movswq -0x5a(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x58(%rbp),%rax
movswq -0x5a(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x48(%rbp),%rax
movswq -0x5a(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
call   1030 <exp@plt>
movaps %xmm0,%xmm2
movsd  -0x68(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    1214 <rq_pricing_bond_opt+0xf4>
mov    -0x5a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x5a(%rbp)
jmp    1166 <rq_pricing_bond_opt+0x46>
mov    -0x2(%rbp),%ax
movsd  -0x10(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm4
movsd  -0x30(%rbp),%xmm5
movsd  -0x38(%rbp),%xmm6
xorps  %xmm3,%xmm3
movswl %ax,%edi
call   1040 <rq_pricing_blackscholes@plt>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rq_pricing_bond_opt>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
movsd  %xmm5,0x18(%rsp)
movapd %xmm4,%xmm5
movsd  %xmm3,0x10(%rsp)
movsd  %xmm2,0x8(%rsp)
movsd  %xmm1,(%rsp)
movapd %xmm0,%xmm1
mov    %edi,%r12d
test   %si,%si
jle    11c7 <rq_pricing_bond_opt+0xa7>
mov    %r8,%r14
mov    %rcx,%r15
mov    %rdx,%r13
movzwl %si,%ebp
xor    %ebx,%ebx
movsd  %xmm5,0x20(%rsp)
jmp    1179 <rq_pricing_bond_opt+0x59>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rbx
cmp    %rbx,%rbp
je     11c7 <rq_pricing_bond_opt+0xa7>
movsd  0x0(%r13,%rbx,8),%xmm0
ucomisd %xmm0,%xmm5
jb     1170 <rq_pricing_bond_opt+0x50>
movsd  (%r15,%rbx,8),%xmm2
movsd  %xmm2,0x28(%rsp)
movsd  %xmm1,0x30(%rsp)
movsd  (%r14,%rbx,8),%xmm1
xorpd  0xe5a(%rip),%xmm1
mulsd  %xmm1,%xmm0
call   1030 <exp@plt>
movsd  0x30(%rsp),%xmm1
movsd  0x20(%rsp),%xmm5
mulsd  0x28(%rsp),%xmm0
subsd  %xmm0,%xmm1
jmp    1170 <rq_pricing_bond_opt+0x50>
movswl %r12w,%edi
xorps  %xmm3,%xmm3
movapd %xmm1,%xmm0
movsd  (%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
movsd  0x10(%rsp),%xmm4
movsd  0x18(%rsp),%xmm6
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1040 <rq_pricing_blackscholes@plt>

LLVM IR (-O0):
define double @rq_pricing_bond_opt(i16 signext %0, double %1, double %2, double %3, double %4, double %5, double %6, i16 signext %7, double* %8, double* %9, double* %10) {
%12 = alloca i16
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca i16
%20 = alloca double*
%21 = alloca double*
%22 = alloca double*
%23 = alloca i16
store i16 %0, i16* %12
store double %1, double* %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 i16 %7, i16* %19
store double* %8, double** %20
store double* %9, double** %21
store double* %10, double** %22
store i16 0, i16* %23
br label %24
24: ; preds = %61, %11
%25 = load i16, i16* %23
%26 = sext i16 %25 to i32
%27 = load i16, i16* %19
%28 = sext i16 %27 to i32
%29 = icmp slt i32 %26, %28
br i1 %29, label %30, label %64
30: ; preds = %24
%31 = load double*, double** %20
%32 = load i16, i16* %23
%33 = sext i16 %32 to i64
%34 = getelementptr inbounds double, double* %31, i64 %33
%35 = load double, double* %34
%36 = load double, double* %17
%37 = fcmp ole double %35, %36
br i1 %37, label %38, label %60
38: ; preds = %30
%39 = load double*, double** %21
%40 = load i16, i16* %23
%41 = sext i16 %40 to i64
%42 = getelementptr inbounds double, double* %39, i64 %41
%43 = load double, double* %42
%44 = load double*, double** %22
%45 = load i16, i16* %23
%46 = sext i16 %45 to i64
%47 = getelementptr inbounds double, double* %44, i64 %46
%48 = load double, double* %47
%49 = fneg double %48
%50 = load double*, double** %20
%51 = load i16, i16* %23
%52 = sext i16 %51 to i64
%53 = getelementptr inbounds double, double* %50, i64 %52
%54 = load double, double* %53
%55 = fmul double %49, %54
%56 = call double @exp(double %55)
%57 = load double, double* %13
%58 = fneg double %43
%59 = call double @llvm.fmuladd.f64(double %58, double %56, double %57)
store double %59, double* %13
br label %60
60: ; preds = %38, %30
br label %61
61: ; preds = %60
%62 = load i16, i16* %23
%63 = add i16 %62, 1
store i16 %63, i16* %23
br label %24
64: ; preds = %24
%65 = load i16, i16* %12
%66 = load double, double* %13
%67 = load double, double* %14
%68 = load double, double* %15
%69 = load double, double* %16
%70 = load double, double* %17
%71 = load double, double* %18
%72 = call double @rq_pricing_blackscholes(i16 signext %65, double %66, double %67, double %68, double 0.000000e+00, double %69, double %70, double %71)
ret double %72
}

LLVM IR (-O2):
define double @rq_pricing_bond_opt(i16 signext %0, double %1, double %2, double %3, double %4, double %5, double %6, i16 signext %7, double* nocapture %8, double* nocapture %9, double* nocapture %10) {
%12 = icmp sgt i16 %7, 0
br i1 %12, label %13, label %35
13: ; preds = %11
%14 = zext i16 %7 to i64
br label %15
15: ; preds = %13, %31
%16 = phi i64 [ 0, %13 ], [ %33, %31 ]
%17 = phi double [ %1, %13 ], [ %32, %31 ]
%18 = getelementptr inbounds double, double* %8, i64 %16
%19 = load double, double* %18
%20 = fcmp ugt double %19, %5
br i1 %20, label %31, label %21
21: ; preds = %15
%22 = getelementptr inbounds double, double* %9, i64 %16
%23 = load double, double* %22
%24 = getelementptr inbounds double, double* %10, i64 %16
%25 = load double, double* %24
%26 = fneg double %25
%27 = fmul double %19, %26
%28 = tail call double @exp(double %27)
%29 = fneg double %23
%30 = tail call double @llvm.fmuladd.f64(double %29, double %28, double %17)
br label %31
31: ; preds = %15, %21
%32 = phi double [ %30, %21 ], [ %17, %15 ]
%33 = add nuw nsw i64 %16, 1
%34 = icmp eq i64 %33, %14
br i1 %34, label %35, label %15
35: ; preds = %31, %11
%36 = phi double [ %1, %11 ], [ %32, %31 ]
%37 = tail call double @rq_pricing_blackscholes(i16 signext %0, double %36, double %2, double %3, double 0.000000e+00, double %4, double %5, double %6)
ret double %37
}