double trapzd(double (*func)(double), double a, double b, int n) {
  long double x, tnm, sum, del;
  static long double s;
  static int it;
  int j;
  if (n == 1) {
    it = 1;
    s = 0.5 * (b - a) * (func(a) + func(b));
    return s;
  } else {
    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);
    it *= 2;
    s = 0.5 * (s + (b - a) * sum / tnm);
    return s;
  }
}


x86 assembly (clang, -O0):
<trapzd>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %esi,-0x24(%rbp)
cmpl   $0x1,-0x24(%rbp)
jne    11b8 <trapzd+0xb8>
movl   $0x1,0x2f10(%rip)
movsd  -0x20(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
subsd  %xmm0,%xmm1
movsd  0xec2(%rip),%xmm2
mulsd  %xmm2,%xmm1
movsd  %xmm1,-0xb8(%rbp)
ff
mov    -0x10(%rbp),%rax
call   *%rax
movsd  %xmm0,-0xc0(%rbp)
ff
mov    -0x10(%rbp),%rax
movsd  -0x20(%rbp),%xmm0
call   *%rax
movsd  -0xc0(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0xb8(%rbp),%xmm0
ff
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
fldl   -0xa8(%rbp)
fstpt  0x2e96(%rip)
fldt   0x2e90(%rip)
fstpl  -0xb0(%rbp)
movsd  -0xb0(%rbp),%xmm0
ff
movsd  %xmm0,-0x8(%rbp)
jmp    12bc <trapzd+0x1bc>
mov    0x2e82(%rip),%eax
mov    %eax,-0x78(%rbp)
fildl  -0x78(%rbp)
fstpt  -0x50(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
fldl   -0x80(%rbp)
fldt   -0x50(%rbp)
fdivrp %st,%st(1)
fstpt  -0x70(%rbp)
fldl   -0x18(%rbp)
fldt   -0x70(%rbp)
flds   0xe0f(%rip)
fmulp  %st,%st(1)
faddp  %st,%st(1)
fstpt  -0x40(%rbp)
fldz
fstpt  -0x60(%rbp)
movl   $0x1,-0x74(%rbp)
mov    -0x74(%rbp),%eax
cmp    0x2e33(%rip),%eax
jg     1259 <trapzd+0x159>
mov    -0x10(%rbp),%rax
fldt   -0x40(%rbp)
fstpl  -0x98(%rbp)
movsd  -0x98(%rbp),%xmm0
ff
call   *%rax
movsd  %xmm0,-0xa0(%rbp)
ff
fldl   -0xa0(%rbp)
fldt   -0x60(%rbp)
faddp  %st,%st(1)
fstpt  -0x60(%rbp)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
fldt   -0x70(%rbp)
fldt   -0x40(%rbp)
faddp  %st,%st(1)
fstpt  -0x40(%rbp)
jmp    1204 <trapzd+0x104>
mov    0x2de1(%rip),%eax
add    %eax,%eax
mov    %eax,0x2dd9(%rip)
fldt   0x2dc3(%rip)
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
fldl   -0x88(%rbp)
fldt   -0x60(%rbp)
fmulp  %st,%st(1)
fldt   -0x50(%rbp)
fdivrp %st,%st(1)
faddp  %st,%st(1)
flds   0xd65(%rip)
fmulp  %st,%st(1)
fstpt  0x2d8d(%rip)
fldt   0x2d87(%rip)
fstpl  -0x90(%rbp)
movsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<trapzd>:
push   %rbp
push   %rbx
sub    $0x78,%rsp
mov    %rdi,%rbx
cmp    $0x1,%esi
jne    1163 <trapzd+0x63>
movl   $0x1,0x2f28(%rip)
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
mulsd  0xee0(%rip),%xmm2
movsd  %xmm2,(%rsp)
movsd  %xmm1,0x10(%rsp)
call   *%rbx
movsd  %xmm0,0x20(%rsp)
movsd  0x10(%rsp),%xmm0
call   *%rbx
addsd  0x20(%rsp),%xmm0
mulsd  (%rsp),%xmm0
movsd  %xmm0,0x30(%rsp)
fldl   0x30(%rsp)
fstpt  0x2ed2(%rip)
jmp    1237 <trapzd+0x137>
mov    0x2ed7(%rip),%eax
mov    %eax,0x1c(%rsp)
fildl  0x1c(%rsp)
subsd  %xmm0,%xmm1
movsd  %xmm1,0x58(%rsp)
fldl   0x58(%rsp)
fld    %st(1)
fstpt  0x6c(%rsp)
fld    %st(0)
fstpt  0x60(%rsp)
fdivp  %st,%st(1)
fstpt  0x10(%rsp)
fldz
test   %eax,%eax
fldz
jle    1201 <trapzd+0x101>
fstp   %st(0)
fstp   %st(0)
movsd  %xmm0,0x50(%rsp)
fldt   0x10(%rsp)
fmuls  0xe53(%rip)
faddl  0x50(%rsp)
fldz
xor    %ebp,%ebp
fxch   %st(1)
nopw   0x0(%rax,%rax,1)
fld    %st(0)
fstpt  (%rsp)
fxch   %st(1)
fstpt  0x20(%rsp)
fstpl  0x48(%rsp)
movsd  0x48(%rsp),%xmm0
call   *%rbx
fldt   0x20(%rsp)
movsd  %xmm0,0x40(%rsp)
faddl  0x40(%rsp)
fldt   0x10(%rsp)
fldt   (%rsp)
faddp  %st,%st(1)
fstpt  (%rsp)
fldt   (%rsp)
mov    0x2e46(%rip),%eax
add    $0x1,%ebp
cmp    %eax,%ebp
jl     11c0 <trapzd+0xc0>
fstp   %st(0)
add    %eax,%eax
fldt   0x2e25(%rip)
fldt   0x60(%rsp)
fmulp  %st,%st(2)
fldt   0x6c(%rsp)
fdivrp %st,%st(2)
faddp  %st,%st(1)
fmuls  0xde1(%rip)
mov    %eax,0x2e1b(%rip)
fld    %st(0)
fstpt  0x2e03(%rip)
fstpl  0x38(%rsp)
movsd  0x38(%rsp),%xmm0
add    $0x78,%rsp
pop    %rbx
pop    %rbp
ret

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

LLVM IR (-O2):
@trapzd.s = internal unnamed_addr global x86_fp80 0xK00000000000000000000
@trapzd.it = internal unnamed_addr global i32 0
define double @trapzd(double (double)* nocapture %0, double %1, double %2, i32 %3) {
%5 = icmp eq i32 %3, 1
br i1 %5, label %6, label %14
6: ; preds = %4
store i32 1, i32* @trapzd.it
%7 = fsub double %2, %1
%8 = fmul double %7, 5.000000e-01
%9 = tail call double %0(double %1)
%10 = tail call double %0(double %2)
%11 = fadd double %9, %10
%12 = fmul double %8, %11
%13 = fpext double %12 to x86_fp80
store x86_fp80 %13, x86_fp80* @trapzd.s
br label %46
14: ; preds = %4
%15 = load i32, i32* @trapzd.it
%16 = sitofp i32 %15 to x86_fp80
%17 = fsub double %2, %1
%18 = fpext double %17 to x86_fp80
%19 = fdiv x86_fp80 %18, %16
%20 = icmp slt i32 %15, 1
br i1 %20, label %36, label %21
21: ; preds = %14
%22 = fpext double %1 to x86_fp80
%23 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %19, x86_fp80 0xK3FFE8000000000000000, x86_fp80 %22)
br label %24
24: ; preds = %21, %24
%25 = phi i32 [ %32, %24 ], [ 1, %21 ]
%26 = phi x86_fp80 [ %33, %24 ], [ %23, %21 ]
%27 = phi x86_fp80 [ %31, %24 ], [ 0xK00000000000000000000, %21 ]
%28 = fptrunc x86_fp80 %26 to double
%29 = tail call double %0(double %28)
%30 = fpext double %29 to x86_fp80
%31 = fadd x86_fp80 %27, %30
%32 = add nuw nsw i32 %25, 1
%33 = fadd x86_fp80 %19, %26
%34 = load i32, i32* @trapzd.it
%35 = icmp slt i32 %25, %34
br i1 %35, label %24, label %36
36: ; preds = %24, %14
%37 = phi x86_fp80 [ 0xK00000000000000000000, %14 ], [ %31, %24 ]
%38 = phi i32 [ %15, %14 ], [ %34, %24 ]
%39 = shl nsw i32 %38, 1
store i32 %39, i32* @trapzd.it
%40 = load x86_fp80, x86_fp80* @trapzd.s
%41 = fmul x86_fp80 %37, %18
%42 = fdiv x86_fp80 %41, %16
%43 = fadd x86_fp80 %42, %40
%44 = fmul x86_fp80 %43, 0xK3FFE8000000000000000
store x86_fp80 %44, x86_fp80* @trapzd.s
%45 = fptrunc x86_fp80 %44 to double
br label %46
46: ; preds = %36, %6
%47 = phi double [ %12, %6 ], [ %45, %36 ]
ret double %47
}