long double simpsons(long double (*f)(long double), long double a,
                     long double b, int n) {
  long double h = (b - a) / n;
  long double sum = f(a) + f(b);
  while (n - 2) {
    sum += (4 * f((n - 1) * h) + 2 * f((n - 2) * h));
    n = n - 2;
  }
  sum += 4 * f((n - 1) * h);
  return sum *= (h / 3);
}


x86 assembly (clang, -O0):
<simpsons>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
fldt   0x20(%rbp)
fldt   0x10(%rbp)
mov    %rdi,-0x8(%rbp)
fstpt  -0x20(%rbp)
fstpt  -0x30(%rbp)
mov    %esi,-0x34(%rbp)
fldt   -0x30(%rbp)
fldt   -0x20(%rbp)
fsubrp %st,%st(1)
mov    -0x34(%rbp),%eax
mov    %eax,-0x64(%rbp)
fildl  -0x64(%rbp)
fdivrp %st,%st(1)
fstpt  -0x50(%rbp)
mov    -0x8(%rbp),%rax
fldt   -0x20(%rbp)
mov    %rsp,%rcx
fstpt  (%rcx)
call   *%rax
fstpt  -0x7c(%rbp)
mov    -0x8(%rbp),%rax
fldt   -0x30(%rbp)
mov    %rsp,%rcx
fstpt  (%rcx)
call   *%rax
fldt   -0x7c(%rbp)
faddp  %st,%st(1)
fstpt  -0x60(%rbp)
mov    -0x34(%rbp),%eax
sub    $0x2,%eax
cmp    $0x0,%eax
je     11d2 <simpsons+0xd2>
mov    -0x8(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x70(%rbp)
fildl  -0x70(%rbp)
fldt   -0x50(%rbp)
fmulp  %st,%st(1)
mov    %rsp,%rcx
fstpt  (%rcx)
call   *%rax
fstpt  -0x88(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0xfffffffe,%ecx
mov    %ecx,-0x6c(%rbp)
fildl  -0x6c(%rbp)
fldt   -0x50(%rbp)
fmulp  %st,%st(1)
mov    %rsp,%rcx
fstpt  (%rcx)
call   *%rax
fldt   -0x88(%rbp)
fxch   %st(1)
fadd   %st,%st(0)
flds   0xe48(%rip)
fmulp  %st,%st(2)
faddp  %st,%st(1)
fldt   -0x60(%rbp)
faddp  %st,%st(1)
fstpt  -0x60(%rbp)
mov    -0x34(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x34(%rbp)
jmp    115b <simpsons+0x5b>
mov    -0x8(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x68(%rbp)
fildl  -0x68(%rbp)
fldt   -0x50(%rbp)
fmulp  %st,%st(1)
mov    %rsp,%rcx
fstpt  (%rcx)
call   *%rax
fldt   -0x60(%rbp)
flds   0xe09(%rip)
fmulp  %st,%st(2)
faddp  %st,%st(1)
fstpt  -0x60(%rbp)
fldt   -0x50(%rbp)
flds   0xdfd(%rip)
fdivrp %st,%st(1)
fldt   -0x60(%rbp)
fmulp  %st,%st(1)
fld    %st(0)
fstpt  -0x60(%rbp)
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<simpsons>:
push   %r14
push   %rbx
sub    $0x48,%rsp
mov    %esi,%ebx
mov    %rdi,%r14
fldt   0x60(%rsp)
fldt   0x70(%rsp)
fld    %st(0)
fstpt  0x24(%rsp)
fsub   %st(1),%st
mov    %esi,0x38(%rsp)
fidivl 0x38(%rsp)
fstpt  0x18(%rsp)
fstpt  (%rsp)
call   *%rdi
fstpt  0x3c(%rsp)
fldt   0x24(%rsp)
fstpt  (%rsp)
call   *%r14
fldt   0x3c(%rsp)
faddp  %st,%st(1)
add    $0xfffffffe,%ebx
fstpt  0x24(%rsp)
je     119c <simpsons+0x9c>
fldt   0x18(%rsp)
fstp   %st(0)
lea    0x1(%rbx),%eax
mov    %eax,0x34(%rsp)
fldt   0x18(%rsp)
fimull 0x34(%rsp)
fstpt  (%rsp)
call   *%r14
fstpt  0x3c(%rsp)
mov    %ebx,0x30(%rsp)
fldt   0x18(%rsp)
fimull 0x30(%rsp)
fstpt  (%rsp)
call   *%r14
fldt   0x3c(%rsp)
fmuls  0xe7b(%rip)
fxch   %st(1)
fadd   %st,%st(0)
faddp  %st,%st(1)
fldt   0x24(%rsp)
faddp  %st,%st(1)
fstpt  0x24(%rsp)
add    $0xfffffffe,%ebx
jne    1150 <simpsons+0x50>
jmp    11a2 <simpsons+0xa2>
fldt   0x18(%rsp)
fstp   %st(0)
fldt   0x18(%rsp)
fstpt  (%rsp)
call   *%r14
fmuls  0xe4e(%rip)
fldt   0x24(%rsp)
faddp  %st,%st(1)
fldt   0x18(%rsp)
fdivs  0xe42(%rip)
fmulp  %st,%st(1)
add    $0x48,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define x86_fp80 @simpsons(x86_fp80 (x86_fp80)* %0, x86_fp80 %1, x86_fp80 %2, i32 %3) {
%5 = alloca x86_fp80 (x86_fp80)*
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca i32
%9 = alloca x86_fp80
%10 = alloca x86_fp80
store x86_fp80 (x86_fp80)* %0, x86_fp80 (x86_fp80)** %5
store x86_fp80 %1, x86_fp80* %6
store x86_fp80 %2, x86_fp80* %7
store i32 %3, i32* %8
%11 = load x86_fp80, x86_fp80* %7
%12 = load x86_fp80, x86_fp80* %6
%13 = fsub x86_fp80 %11, %12
%14 = load i32, i32* %8
%15 = sitofp i32 %14 to x86_fp80
%16 = fdiv x86_fp80 %13, %15
store x86_fp80 %16, x86_fp80* %9
%17 = load x86_fp80 (x86_fp80)*, x86_fp80 (x86_fp80)** %5
%18 = load x86_fp80, x86_fp80* %6
%19 = call x86_fp80 %17(x86_fp80 %18)
%20 = load x86_fp80 (x86_fp80)*, x86_fp80 (x86_fp80)** %5
%21 = load x86_fp80, x86_fp80* %7
%22 = call x86_fp80 %20(x86_fp80 %21)
%23 = fadd x86_fp80 %19, %22
store x86_fp80 %23, x86_fp80* %10
br label %24
24: ; preds = %28, %4
%25 = load i32, i32* %8
%26 = sub nsw i32 %25, 2
%27 = icmp ne i32 %26, 0
br i1 %27, label %28, label %49
28: ; preds = %24
%29 = load x86_fp80 (x86_fp80)*, x86_fp80 (x86_fp80)** %5
%30 = load i32, i32* %8
%31 = sub nsw i32 %30, 1
%32 = sitofp i32 %31 to x86_fp80
%33 = load x86_fp80, x86_fp80* %9
%34 = fmul x86_fp80 %32, %33
%35 = call x86_fp80 %29(x86_fp80 %34)
%36 = load x86_fp80 (x86_fp80)*, x86_fp80 (x86_fp80)** %5
%37 = load i32, i32* %8
%38 = sub nsw i32 %37, 2
%39 = sitofp i32 %38 to x86_fp80
%40 = load x86_fp80, x86_fp80* %9
%41 = fmul x86_fp80 %39, %40
%42 = call x86_fp80 %36(x86_fp80 %41)
%43 = fmul x86_fp80 0xK40008000000000000000, %42
%44 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 0xK40018000000000000000, x86_fp80 %35, x86_fp80 %43)
%45 = load x86_fp80, x86_fp80* %10
%46 = fadd x86_fp80 %45, %44
store x86_fp80 %46, x86_fp80* %10
%47 = load i32, i32* %8
%48 = sub nsw i32 %47, 2
store i32 %48, i32* %8
br label %24
49: ; preds = %24
%50 = load x86_fp80 (x86_fp80)*, x86_fp80 (x86_fp80)** %5
%51 = load i32, i32* %8
%52 = sub nsw i32 %51, 1
%53 = sitofp i32 %52 to x86_fp80
%54 = load x86_fp80, x86_fp80* %9
%55 = fmul x86_fp80 %53, %54
%56 = call x86_fp80 %50(x86_fp80 %55)
%57 = load x86_fp80, x86_fp80* %10
%58 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 0xK40018000000000000000, x86_fp80 %56, x86_fp80 %57)
store x86_fp80 %58, x86_fp80* %10
%59 = load x86_fp80, x86_fp80* %9
%60 = fdiv x86_fp80 %59, 0xK4000C000000000000000
%61 = load x86_fp80, x86_fp80* %10
%62 = fmul x86_fp80 %61, %60
store x86_fp80 %62, x86_fp80* %10
ret x86_fp80 %62
}

LLVM IR (-O2):
define x86_fp80 @simpsons(x86_fp80 (x86_fp80)* nocapture %0, x86_fp80 %1, x86_fp80 %2, i32 %3) {
%5 = fsub x86_fp80 %2, %1
%6 = sitofp i32 %3 to x86_fp80
%7 = fdiv x86_fp80 %5, %6
%8 = tail call x86_fp80 %0(x86_fp80 %1)
%9 = tail call x86_fp80 %0(x86_fp80 %2)
%10 = fadd x86_fp80 %8, %9
%11 = add nsw i32 %3, -2
%12 = icmp eq i32 %11, 0
br i1 %12, label %29, label %13
13: ; preds = %4, %13
%14 = phi i32 [ %27, %13 ], [ %11, %4 ]
%15 = phi x86_fp80 [ %26, %13 ], [ %10, %4 ]
%16 = phi i32 [ %14, %13 ], [ %3, %4 ]
%17 = add nsw i32 %16, -1
%18 = sitofp i32 %17 to x86_fp80
%19 = fmul x86_fp80 %7, %18
%20 = tail call x86_fp80 %0(x86_fp80 %19)
%21 = sitofp i32 %14 to x86_fp80
%22 = fmul x86_fp80 %7, %21
%23 = tail call x86_fp80 %0(x86_fp80 %22)
%24 = fmul x86_fp80 %23, 0xK40008000000000000000
%25 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %20, x86_fp80 0xK40018000000000000000, x86_fp80 %24)
%26 = fadd x86_fp80 %15, %25
%27 = add nsw i32 %14, -2
%28 = icmp eq i32 %27, 0
br i1 %28, label %29, label %13
29: ; preds = %13, %4
%30 = phi x86_fp80 [ %10, %4 ], [ %26, %13 ]
%31 = tail call x86_fp80 %0(x86_fp80 %7)
%32 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %31, x86_fp80 0xK40018000000000000000, x86_fp80 %30)
%33 = fdiv x86_fp80 %7, 0xK4000C000000000000000
%34 = fmul x86_fp80 %33, %32
ret x86_fp80 %34
}