double trapzd3(double (*func)(double), 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) * (((*func)(a)) + ((*func)(b))));
  } 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 += ((*func)(x));
    s = 0.5 * (s + (b - a) * sum / tnm);
    return s;
  }
}


x86 assembly (clang, -O0):
<trapzd3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %esi,-0x24(%rbp)
cmpl   $0x1,-0x24(%rbp)
jne    1180 <trapzd3+0x80>
movsd  -0x20(%rbp),%xmm1
subsd  -0x18(%rbp),%xmm1
movsd  0xecb(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movsd  -0x18(%rbp),%xmm0
call   *%rax
movsd  %xmm0,-0x60(%rbp)
mov    -0x10(%rbp),%rax
movsd  -0x20(%rbp),%xmm0
call   *%rax
movsd  -0x60(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x58(%rbp),%xmm0
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x2eb2(%rip)
movsd  %xmm0,-0x8(%rbp)
jmp    1281 <trapzd3+0x181>
movl   $0x1,-0x4c(%rbp)
movl   $0x1,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    11b6 <trapzd3+0xb6>
mov    -0x4c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
jmp    118e <trapzd3+0x8e>
cvtsi2sdl -0x4c(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
divsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x48(%rbp),%xmm0
movsd  0xe1a(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x1,-0x50(%rbp)
mov    -0x50(%rbp),%eax
cmp    -0x4c(%rbp),%eax
jg     1240 <trapzd3+0x140>
mov    -0x10(%rbp),%rax
movsd  -0x30(%rbp),%xmm0
call   *%rax
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1202 <trapzd3+0x102>
movsd  0x2de0(%rip),%xmm1
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
divsd  -0x38(%rbp),%xmm0
addsd  %xmm0,%xmm1
movsd  0xd98(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x2db4(%rip)
movsd  0x2dac(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<trapzd3>:
push   %rbp
push   %rbx
sub    $0x28,%rsp
mov    %rdi,%rbx
cmp    $0x1,%esi
jne    114d <trapzd3+0x4d>
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
mulsd  0xeea(%rip),%xmm2
movsd  %xmm2,(%rsp)
movsd  %xmm1,0x8(%rsp)
call   *%rbx
movsd  %xmm0,0x18(%rsp)
movsd  0x8(%rsp),%xmm0
call   *%rbx
movapd %xmm0,%xmm1
addsd  0x18(%rsp),%xmm1
mulsd  (%rsp),%xmm1
jmp    123f <trapzd3+0x13f>
cmp    $0x3,%esi
jl     1169 <trapzd3+0x69>
lea    -0x2(%rsi),%ecx
add    $0xfffffffd,%esi
mov    %ecx,%eax
and    $0x7,%eax
cmp    $0x7,%esi
jae    1188 <trapzd3+0x88>
mov    $0x1,%ebp
jmp    1198 <trapzd3+0x98>
subsd  %xmm0,%xmm1
mov    $0x1,%ebp
movsd  0xe86(%rip),%xmm2
movsd  %xmm2,0x20(%rsp)
movsd  %xmm1,0x8(%rsp)
jmp    11c3 <trapzd3+0xc3>
and    $0xfffffff8,%ecx
mov    $0x1,%ebp
shl    $0x8,%ebp
add    $0xfffffff8,%ecx
jne    1190 <trapzd3+0x90>
test   %eax,%eax
je     11a7 <trapzd3+0xa7>
nopl   0x0(%rax)
add    %ebp,%ebp
add    $0xffffffff,%eax
jne    11a0 <trapzd3+0xa0>
cvtsi2sd %ebp,%xmm2
subsd  %xmm0,%xmm1
test   %ebp,%ebp
jle    1223 <trapzd3+0x123>
movsd  %xmm1,0x8(%rsp)
movsd  %xmm2,0x20(%rsp)
divsd  %xmm2,%xmm1
movsd  %xmm1,0x10(%rsp)
movsd  0xe37(%rip),%xmm1
mulsd  0x10(%rsp),%xmm1
addsd  %xmm0,%xmm1
xorpd  %xmm0,%xmm0
nop
movsd  %xmm1,0x18(%rsp)
movsd  %xmm0,(%rsp)
movapd %xmm1,%xmm0
call   *%rbx
movsd  (%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
movsd  0x18(%rsp),%xmm1
movsd  (%rsp),%xmm0
addsd  0x10(%rsp),%xmm1
add    $0xffffffff,%ebp
jne    11e0 <trapzd3+0xe0>
movsd  0x8(%rsp),%xmm1
movsd  0x20(%rsp),%xmm2
jmp    1227 <trapzd3+0x127>
xorpd  %xmm0,%xmm0
mulsd  %xmm0,%xmm1
divsd  %xmm2,%xmm1
addsd  0x2df1(%rip),%xmm1
mulsd  0xdc9(%rip),%xmm1
movsd  %xmm1,0x2de1(%rip)
movapd %xmm1,%xmm0
add    $0x28,%rsp
pop    %rbx
pop    %rbp
ret

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

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