double simpson1D(double x, int sdiv, double (*f)(double, double, void *),
                 double (*c)(double, void *), double (*d)(double, void *),
                 void *info) {
  double k, sum1 = 0, sum2 = 0, ca, da;
  int i;
  ca = c(x, info);
  da = d(x, info);
  k = ((double)da - ca) / ((double)2 * sdiv);
  for (i = 1; i < sdiv; i++) {
    sum1 += f(x, ca + k * 2 * i, info);
    sum2 += f(x, ca + k * (2 * i - 1), info);
  }
  sum2 += f(x, ca + k * (2 * i - 1), info);
  return ((double)(k / 3) *
          (f(x, ca, info) + f(x, da, info) + 2 * sum1 + 4 * sum2));
}


x86 assembly (clang, -O0):
<simpson1D>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
mov    -0x30(%rbp),%rdi
call   *%rax
movsd  %xmm0,-0x50(%rbp)
mov    -0x28(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
mov    -0x30(%rbp),%rdi
call   *%rax
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
cvtsi2sdl -0xc(%rbp),%xmm2
movsd  0xe91(%rip),%xmm1
mulsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movl   $0x1,-0x5c(%rbp)
mov    -0x5c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    120d <simpson1D+0x10d>
mov    -0x18(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  0xe5b(%rip),%xmm1
mulsd  -0x38(%rbp),%xmm1
cvtsi2sdl -0x5c(%rbp),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mov    -0x30(%rbp),%rdi
call   *%rax
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mov    -0x5c(%rbp),%ecx
shl    $0x1,%ecx
sub    $0x1,%ecx
cvtsi2sd %ecx,%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mov    -0x30(%rbp),%rdi
call   *%rax
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    1183 <simpson1D+0x83>
mov    -0x18(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mov    -0x5c(%rbp),%ecx
shl    $0x1,%ecx
sub    $0x1,%ecx
cvtsi2sd %ecx,%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mov    -0x30(%rbp),%rdi
call   *%rax
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  0xdbe(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x18(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm1
mov    -0x30(%rbp),%rdi
call   *%rax
movsd  %xmm0,-0x70(%rbp)
mov    -0x18(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
mov    -0x30(%rbp),%rdi
call   *%rax
movsd  -0x70(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x68(%rbp),%xmm0
addsd  %xmm2,%xmm1
movsd  -0x40(%rbp),%xmm2
addsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
movsd  -0x48(%rbp),%xmm1
movsd  0xd55(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<simpson1D>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    %r8,%r13
mov    %rcx,%r12
mov    %rsi,%r14
mov    %edi,%r15d
movsd  %xmm0,0x8(%rsp)
mov    %r8,%rdi
call   *%rdx
movsd  %xmm0,0x18(%rsp)
movsd  0x8(%rsp),%xmm0
mov    %r13,%rdi
call   *%r12
movsd  0x18(%rsp),%xmm3
movsd  %xmm0,0x30(%rsp)
movapd %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsi2sd %r15d,%xmm0
subsd  %xmm3,%xmm1
addsd  %xmm0,%xmm0
divsd  %xmm0,%xmm1
cmp    $0x2,%r15d
movsd  %xmm1,0x20(%rsp)
jl     1231 <simpson1D+0x131>
movapd %xmm1,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x38(%rsp)
lea    -0x1(%r15),%ebp
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0xe71(%rip),%xmm2
mov    $0x1,%ebx
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x10(%rsp)
xchg   %ax,%ax
movsd  %xmm2,0x40(%rsp)
movsd  0x38(%rsp),%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm3,%xmm1
movsd  0x8(%rsp),%xmm0
mov    %r13,%rdi
call   *%r14
movsd  0x28(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x28(%rsp)
xorps  %xmm1,%xmm1
cvtsi2sd %ebx,%xmm1
mulsd  0x20(%rsp),%xmm1
addsd  0x18(%rsp),%xmm1
movsd  0x8(%rsp),%xmm0
mov    %r13,%rdi
call   *%r14
movsd  0x40(%rsp),%xmm2
movsd  0x18(%rsp),%xmm3
movsd  0x10(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
addsd  0xded(%rip),%xmm2
add    $0x2,%ebx
add    $0xffffffff,%ebp
jne    11a0 <simpson1D+0xa0>
movsd  0x20(%rsp),%xmm2
lea    (%r15,%r15,1),%eax
add    $0xffffffff,%eax
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
jmp    1251 <simpson1D+0x151>
movapd %xmm1,%xmm2
movsd  0xdc3(%rip),%xmm1
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x10(%rsp)
xorpd  %xmm0,%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0x8(%rsp),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm3,%xmm1
mov    %r13,%rdi
call   *%r14
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0x20(%rsp),%xmm0
divsd  0xd89(%rip),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0x8(%rsp),%xmm0
movsd  0x18(%rsp),%xmm1
mov    %r13,%rdi
call   *%r14
movsd  %xmm0,0x18(%rsp)
movsd  0x8(%rsp),%xmm0
movsd  0x30(%rsp),%xmm1
mov    %r13,%rdi
call   *%r14
addsd  0x18(%rsp),%xmm0
movsd  0x28(%rsp),%xmm1
addsd  %xmm1,%xmm1
addsd  %xmm1,%xmm0
movsd  0x10(%rsp),%xmm1
mulsd  0xd3f(%rip),%xmm1
addsd  %xmm1,%xmm0
mulsd  0x20(%rsp),%xmm0
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define double @simpson1D(double %0, i32 %1, double (double, double, i8*)* nocapture %2, double (double, i8*)* nocapture %3, double (double, i8*)* nocapture %4, i8* %5) {
%7 = tail call double %3(double %0, i8* %5)
%8 = tail call double %4(double %0, i8* %5)
%9 = fsub double %8, %7
%10 = sitofp i32 %1 to double
%11 = fmul double %10, 2.000000e+00
%12 = fdiv double %9, %11
%13 = icmp sgt i32 %1, 1
br i1 %13, label %14, label %36
14: ; preds = %6
%15 = fmul double %12, 2.000000e+00
br label %16
16: ; preds = %14, %16
%17 = phi i32 [ 1, %14 ], [ %30, %16 ]
%18 = phi double [ 0.000000e+00, %14 ], [ %23, %16 ]
%19 = phi double [ 0.000000e+00, %14 ], [ %29, %16 ]
%20 = sitofp i32 %17 to double
%21 = tail call double @llvm.fmuladd.f64(double %15, double %20, double %7)
%22 = tail call double %2(double %0, double %21, i8* %5)
%23 = fadd double %18, %22
%24 = shl nuw nsw i32 %17, 1
%25 = add nsw i32 %24, -1
%26 = sitofp i32 %25 to double
%27 = tail call double @llvm.fmuladd.f64(double %12, double %26, double %7)
%28 = tail call double %2(double %0, double %27, i8* %5)
%29 = fadd double %19, %28
%30 = add nuw nsw i32 %17, 1
%31 = icmp eq i32 %30, %1
br i1 %31, label %32, label %16
32: ; preds = %16
%33 = shl i32 %1, 1
%34 = add i32 %33, -1
%35 = sitofp i32 %34 to double
br label %36
36: ; preds = %32, %6
%37 = phi double [ 0.000000e+00, %6 ], [ %29, %32 ]
%38 = phi double [ 0.000000e+00, %6 ], [ %23, %32 ]
%39 = phi double [ 1.000000e+00, %6 ], [ %35, %32 ]
%40 = tail call double @llvm.fmuladd.f64(double %12, double %39, double %7)
%41 = tail call double %2(double %0, double %40, i8* %5)
%42 = fadd double %37, %41
%43 = fdiv double %12, 3.000000e+00
%44 = tail call double %2(double %0, double %7, i8* %5)
%45 = tail call double %2(double %0, double %8, i8* %5)
%46 = fadd double %44, %45
%47 = tail call double @llvm.fmuladd.f64(double %38, double 2.000000e+00, double %46)
%48 = tail call double @llvm.fmuladd.f64(double %42, double 4.000000e+00, double %47)
%49 = fmul double %43, %48
ret double %49
}