double trapzd(double (*funcd)(), double es, double Wind, double AirDens,
              double ZO, double EactAir, double F, double hsalt, double phi_r,
              double ushear, double Zrh, double a, double b, int n) {
  double x, tnm, sum, del;
  static double s;
  int it, j;
  if (n == 1) {
    return (s = 0.5 * (b - a) *
                ((*funcd)(a, es, Wind, AirDens, ZO, EactAir, F, hsalt, phi_r,
                          ushear, Zrh) +
                 (*funcd)(b, es, Wind, AirDens, ZO, EactAir, F, hsalt, phi_r,
                          ushear, Zrh)));
  } else {
    for (it = 1, j = 1; j < n - 1; j++)
      it <<= 1;
    tnm = it;
    del = (b - a) / tnm;
    x = a + 0.5 * del;
    for (sum = 0.0, j = 1; j <= it; j++, x += del)
      sum += (*funcd)(x, es, Wind, AirDens, ZO, EactAir, F, hsalt, phi_r,
                      ushear, Zrh);
    s = 0.5 * (s + (b - a) * sum / tnm);
    return s;
  }
}


x86 assembly (clang, -O0):
<trapzd>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
movsd  0x28(%rbp),%xmm8
movsd  0x20(%rbp),%xmm8
movsd  0x18(%rbp),%xmm8
movsd  0x10(%rbp),%xmm8
mov    %rdi,-0x10(%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  %xmm6,-0x48(%rbp)
movsd  %xmm7,-0x50(%rbp)
mov    %esi,-0x54(%rbp)
cmpl   $0x1,-0x54(%rbp)
jne    125b <trapzd+0x15b>
movsd  0x28(%rbp),%xmm1
subsd  0x20(%rbp),%xmm1
movsd  0xe92(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
mov    -0x10(%rbp),%rcx
movsd  0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm3
movsd  -0x30(%rbp),%xmm4
movsd  -0x38(%rbp),%xmm5
movsd  -0x40(%rbp),%xmm6
movsd  -0x48(%rbp),%xmm7
movsd  -0x50(%rbp),%xmm10
movsd  0x10(%rbp),%xmm9
movsd  0x18(%rbp),%xmm8
movsd  %xmm10,(%rsp)
movsd  %xmm9,0x8(%rsp)
movsd  %xmm8,0x10(%rsp)
mov    $0x8,%al
call   *%rcx
movsd  %xmm0,-0x90(%rbp)
ff
mov    -0x10(%rbp),%rcx
movsd  0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm3
movsd  -0x30(%rbp),%xmm4
movsd  -0x38(%rbp),%xmm5
movsd  -0x40(%rbp),%xmm6
movsd  -0x48(%rbp),%xmm7
movsd  -0x50(%rbp),%xmm10
movsd  0x10(%rbp),%xmm9
movsd  0x18(%rbp),%xmm8
movsd  %xmm10,(%rsp)
movsd  %xmm9,0x8(%rsp)
movsd  %xmm8,0x10(%rsp)
mov    $0x8,%al
call   *%rcx
movsd  -0x90(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0x88(%rbp),%xmm0
ff
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x2dd7(%rip)
movsd  %xmm0,-0x8(%rbp)
jmp    13a7 <trapzd+0x2a7>
movl   $0x1,-0x7c(%rbp)
movl   $0x1,-0x80(%rbp)
mov    -0x80(%rbp),%eax
mov    -0x54(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1291 <trapzd+0x191>
mov    -0x7c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x7c(%rbp)
mov    -0x80(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x80(%rbp)
jmp    1269 <trapzd+0x169>
cvtsi2sdl -0x7c(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  0x28(%rbp),%xmm0
subsd  0x20(%rbp),%xmm0
divsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  0x20(%rbp),%xmm1
movsd  -0x78(%rbp),%xmm0
movsd  0xd3f(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x70(%rbp)
movl   $0x1,-0x80(%rbp)
mov    -0x80(%rbp),%eax
cmp    -0x7c(%rbp),%eax
jg     1366 <trapzd+0x266>
mov    -0x10(%rbp),%rcx
movsd  -0x60(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm3
movsd  -0x30(%rbp),%xmm4
movsd  -0x38(%rbp),%xmm5
movsd  -0x40(%rbp),%xmm6
movsd  -0x48(%rbp),%xmm7
movsd  -0x50(%rbp),%xmm10
movsd  0x10(%rbp),%xmm9
movsd  0x18(%rbp),%xmm8
movsd  %xmm10,(%rsp)
movsd  %xmm9,0x8(%rsp)
movsd  %xmm8,0x10(%rsp)
mov    $0x8,%al
call   *%rcx
addsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x80(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x80(%rbp)
movsd  -0x78(%rbp),%xmm0
addsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    12dd <trapzd+0x1dd>
movsd  0x2cba(%rip),%xmm1
movsd  0x28(%rbp),%xmm0
subsd  0x20(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
divsd  -0x68(%rbp),%xmm0
addsd  %xmm0,%xmm1
movsd  0xc72(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x2c8e(%rip)
movsd  0x2c86(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<trapzd>:
push   %rbp
push   %rbx
sub    $0x88,%rsp
movapd %xmm7,%xmm8
movaps %xmm6,%xmm13
movaps %xmm5,%xmm10
movaps %xmm4,%xmm11
movaps %xmm3,%xmm4
movaps %xmm2,%xmm3
movaps %xmm1,%xmm2
movaps %xmm0,%xmm1
mov    %rdi,%rbx
movsd  0xb8(%rsp),%xmm9
movsd  0xb0(%rsp),%xmm0
movsd  0xa8(%rsp),%xmm5
movsd  0xa0(%rsp),%xmm6
cmp    $0x1,%esi
jne    1240 <trapzd+0x140>
subsd  %xmm0,%xmm9
mulsd  0xea3(%rip),%xmm9
movsd  %xmm9,0x20(%rsp)
movsd  %xmm5,0x10(%rsp)
movsd  %xmm6,0x8(%rsp)
movsd  %xmm8,(%rsp)
movsd  %xmm2,0x38(%rsp)
movsd  %xmm3,0x40(%rsp)
movsd  %xmm4,0x50(%rsp)
movsd  %xmm11,0x58(%rsp)
movaps %xmm11,%xmm5
movsd  %xmm10,0x60(%rsp)
movaps %xmm10,%xmm6
movsd  %xmm13,0x68(%rsp)
movaps %xmm13,%xmm7
mov    $0x8,%al
movsd  %xmm8,0x48(%rsp)
movsd  %xmm1,0x30(%rsp)
call   *%rbx
movsd  %xmm0,0x70(%rsp)
movsd  0xa8(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0xa0(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x48(%rsp),%xmm0
movsd  %xmm0,(%rsp)
movsd  0xb8(%rsp),%xmm0
movsd  0x30(%rsp),%xmm1
movsd  0x38(%rsp),%xmm2
movsd  0x40(%rsp),%xmm3
movsd  0x50(%rsp),%xmm4
movsd  0x58(%rsp),%xmm5
movsd  0x60(%rsp),%xmm6
movsd  0x68(%rsp),%xmm7
mov    $0x8,%al
call   *%rbx
movapd %xmm0,%xmm9
addsd  0x70(%rsp),%xmm9
mulsd  0x20(%rsp),%xmm9
jmp    13e7 <trapzd+0x2e7>
cmp    $0x3,%esi
jl     125c <trapzd+0x15c>
lea    -0x2(%rsi),%ecx
add    $0xfffffffd,%esi
mov    %ecx,%eax
and    $0x7,%eax
cmp    $0x7,%esi
jae    1280 <trapzd+0x180>
mov    $0x1,%ebp
jmp    1298 <trapzd+0x198>
subsd  %xmm0,%xmm9
mov    $0x1,%ebp
movsd  0xd92(%rip),%xmm7
movsd  %xmm7,0x78(%rsp)
movsd  %xmm9,0x80(%rsp)
jmp    12cf <trapzd+0x1cf>
and    $0xfffffff8,%ecx
mov    $0x1,%ebp
nopl   0x0(%rax,%rax,1)
shl    $0x8,%ebp
add    $0xfffffff8,%ecx
jne    1290 <trapzd+0x190>
test   %eax,%eax
je     12a7 <trapzd+0x1a7>
nopl   0x0(%rax)
add    %ebp,%ebp
add    $0xffffffff,%eax
jne    12a0 <trapzd+0x1a0>
cvtsi2sd %ebp,%xmm12
subsd  %xmm0,%xmm9
test   %ebp,%ebp
jle    13c7 <trapzd+0x2c7>
movsd  %xmm9,0x80(%rsp)
movsd  %xmm12,0x78(%rsp)
divsd  %xmm12,%xmm9
movsd  %xmm9,0x28(%rsp)
movsd  0xd2a(%rip),%xmm7
mulsd  0x28(%rsp),%xmm7
addsd  %xmm0,%xmm7
xorpd  %xmm0,%xmm0
movsd  %xmm13,0x68(%rsp)
movsd  %xmm10,0x60(%rsp)
movsd  %xmm11,0x58(%rsp)
movsd  %xmm4,0x50(%rsp)
movsd  %xmm8,0x48(%rsp)
movsd  %xmm3,0x40(%rsp)
movsd  %xmm2,0x38(%rsp)
movsd  %xmm1,0x30(%rsp)
movsd  %xmm7,0x70(%rsp)
movsd  %xmm0,0x20(%rsp)
movsd  %xmm5,0x10(%rsp)
movsd  %xmm6,0x8(%rsp)
movsd  %xmm8,(%rsp)
movapd %xmm7,%xmm0
movsd  0x38(%rsp),%xmm2
movsd  0x40(%rsp),%xmm3
movsd  0x50(%rsp),%xmm4
movsd  0x58(%rsp),%xmm5
movsd  0x60(%rsp),%xmm6
movsd  0x68(%rsp),%xmm7
mov    $0x8,%al
call   *%rbx
movsd  0xa8(%rsp),%xmm5
movsd  0xa0(%rsp),%xmm6
movsd  0x30(%rsp),%xmm1
movsd  0x48(%rsp),%xmm8
movsd  0x20(%rsp),%xmm7
addsd  %xmm0,%xmm7
movsd  %xmm7,0x20(%rsp)
movsd  0x70(%rsp),%xmm7
movsd  0x20(%rsp),%xmm0
addsd  0x28(%rsp),%xmm7
add    $0xffffffff,%ebp
jne    1320 <trapzd+0x220>
movsd  0x80(%rsp),%xmm9
movsd  0x78(%rsp),%xmm12
jmp    13cb <trapzd+0x2cb>
xorpd  %xmm0,%xmm0
mulsd  %xmm0,%xmm9
divsd  %xmm12,%xmm9
addsd  0x2c4a(%rip),%xmm9
mulsd  0xc21(%rip),%xmm9
movsd  %xmm9,0x2c38(%rip)
movapd %xmm9,%xmm0
add    $0x88,%rsp
pop    %rbx
pop    %rbp
ret

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

LLVM IR (-O2):
@trapzd.s = internal unnamed_addr global double 0.000000e+00
define double @trapzd(double (...)* nocapture %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10, double %11, double %12, i32 %13) {
%15 = icmp eq i32 %13, 1
br i1 %15, label %27, label %16
16: ; preds = %14
%17 = icmp sgt i32 %13, 2
br i1 %17, label %18, label %25
18: ; preds = %16
%19 = add i32 %13, -2
%20 = add i32 %13, -3
%21 = and i32 %19, 7
%22 = icmp ult i32 %20, 7
br i1 %22, label %41, label %23
23: ; preds = %18
%24 = and i32 %19, -8
br label %35
25: ; preds = %16
%26 = fsub double %12, %11
br label %57
27: ; preds = %14
%28 = fsub double %12, %11
%29 = fmul double %28, 5.000000e-01
%30 = bitcast double (...)* %0 to double (double, double, double, double, double, double, double, double, double, double, double, ...)*
%31 = tail call double (double, double, double, double, double, double, double, double, double, double, double, ...) %30(double %11, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10)
%32 = tail call double (double, double, double, double, double, double, double, double, double, double, double, ...) %30(double %12, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10)
%33 = fadd double %31, %32
%34 = fmul double %29, %33
br label %82
35: ; preds = %35, %23
%36 = phi i32 [ 1, %23 ], [ %38, %35 ]
%37 = phi i32 [ 0, %23 ], [ %39, %35 ]
%38 = shl i32 %36, 8
%39 = add i32 %37, 8
%40 = icmp eq i32 %39, %24
br i1 %40, label %41, label %35
41: ; preds = %35, %18
%42 = phi i32 [ undef, %18 ], [ %38, %35 ]
%43 = phi i32 [ 1, %18 ], [ %38, %35 ]
%44 = icmp eq i32 %21, 0
br i1 %44, label %51, label %45
45: ; preds = %41, %45
%46 = phi i32 [ %48, %45 ], [ %43, %41 ]
%47 = phi i32 [ %49, %45 ], [ 0, %41 ]
%48 = shl i32 %46, 1
%49 = add i32 %47, 1
%50 = icmp eq i32 %49, %21
br i1 %50, label %51, label %45
51: ; preds = %45, %41
%52 = phi i32 [ %42, %41 ], [ %48, %45 ]
%53 = sitofp i32 %52 to double
%54 = fsub double %12, %11
%55 = fdiv double %54, %53
%56 = icmp slt i32 %52, 1
br i1 %56, label %73, label %57
57: ; preds = %25, %51
%58 = phi double [ %26, %25 ], [ %55, %51 ]
%59 = phi double [ %26, %25 ], [ %54, %51 ]
%60 = phi double [ 1.000000e+00, %25 ], [ %53, %51 ]
%61 = phi i32 [ 1, %25 ], [ %52, %51 ]
%62 = tail call double @llvm.fmuladd.f64(double %58, double 5.000000e-01, double %11)
%63 = bitcast double (...)* %0 to double (double, double, double, double, double, double, double, double, double, double, double, ...)*
br label %64
64: ; preds = %57, %64
%65 = phi i32 [ 1, %57 ], [ %70, %64 ]
%66 = phi double [ 0.000000e+00, %57 ], [ %69, %64 ]
%67 = phi double [ %62, %57 ], [ %71, %64 ]
%68 = tail call double (double, double, double, double, double, double, double, double, double, double, double, ...) %63(double %67, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10)
%69 = fadd double %66, %68
%70 = add nuw nsw i32 %65, 1
%71 = fadd double %58, %67
%72 = icmp eq i32 %65, %61
br i1 %72, label %73, label %64
73: ; preds = %64, %51
%74 = phi double [ %54, %51 ], [ %59, %64 ]
%75 = phi double [ %53, %51 ], [ %60, %64 ]
%76 = phi double [ 0.000000e+00, %51 ], [ %69, %64 ]
%77 = load double, double* @trapzd.s
%78 = fmul double %74, %76
%79 = fdiv double %78, %75
%80 = fadd double %79, %77
%81 = fmul double %80, 5.000000e-01
br label %82
82: ; preds = %73, %27
%83 = phi double [ %81, %73 ], [ %34, %27 ]
store double %83, double* @trapzd.s
ret double %83
}