float simpson(fcn, x0, xn, n) float (*fcn)();
float x0, xn;
int n;
{
  int i;
  float dx, x, sum;
  dx = (xn - x0) / n;
  sum = (*fcn)(x0) + 4 * (*fcn)(x0 + dx) + (*fcn)(xn);
  for (i = 2; i < n; i += 2) {
    x = x0 + i * dx;
    sum += 2 * (*fcn)(x) + 4 * (*fcn)(x + dx);
  }
  return (sum * dx / 3.0);
}


x86 assembly (clang, -O0):
<simpson>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm1,-0x38(%rbp)
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
cvtsd2ss %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm0
mov    %rdi,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  %xmm0,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movss  -0x10(%rbp),%xmm0
subss  -0xc(%rbp),%xmm0
cvtsi2ssl -0x14(%rbp),%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x8(%rbp),%rcx
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rcx
movss  %xmm0,-0x2c(%rbp)
mov    -0x8(%rbp),%rcx
movss  -0xc(%rbp),%xmm0
addss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rcx
movss  -0x2c(%rbp),%xmm1
movss  0xe81(%rip),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rcx
movss  -0x10(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rcx
movaps %xmm0,%xmm1
movss  -0x28(%rbp),%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
movl   $0x2,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    123d <simpson+0x13d>
movss  -0xc(%rbp),%xmm1
cvtsi2ssl -0x18(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rcx
movss  -0x20(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rcx
movss  %xmm0,-0x3c(%rbp)
mov    -0x8(%rbp),%rcx
movss  -0x20(%rbp),%xmm0
addss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rcx
movaps %xmm0,%xmm2
movss  -0x3c(%rbp),%xmm0
movss  0xde7(%rip),%xmm1
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm0
addss  %xmm1,%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x18(%rbp)
jmp    11b5 <simpson+0xb5>
movss  -0x24(%rbp),%xmm0
mulss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xdb5(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<simpson>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
cvtsd2ss %xmm0,%xmm2
cvtsd2ss %xmm1,%xmm1
movss  %xmm1,0x14(%rsp)
mov    %esi,%r14d
xorps  %xmm0,%xmm0
cvtsi2ss %esi,%xmm0
mov    %rdi,%rbx
movss  %xmm2,0x18(%rsp)
subss  %xmm2,%xmm1
divss  %xmm0,%xmm1
movss  %xmm1,0x10(%rsp)
xorps  %xmm0,%xmm0
cvtss2sd %xmm2,%xmm0
mov    $0x1,%al
call   *%rdi
movss  %xmm0,0xc(%rsp)
movss  0x10(%rsp),%xmm0
addss  0x18(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rbx
mulss  0xe9c(%rip),%xmm0
addss  0xc(%rsp),%xmm0
movss  %xmm0,0xc(%rsp)
movss  0x14(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rbx
addss  0xc(%rsp),%xmm0
cmp    $0x3,%r14d
jl     11f9 <simpson+0xf9>
mov    $0x2,%ebp
nop
movss  %xmm0,0x14(%rsp)
xorps  %xmm0,%xmm0
cvtsi2ss %ebp,%xmm0
mulss  0x10(%rsp),%xmm0
addss  0x18(%rsp),%xmm0
movss  %xmm0,0x1c(%rsp)
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rbx
movss  %xmm0,0xc(%rsp)
movss  0x1c(%rsp),%xmm0
addss  0x10(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
mov    $0x1,%al
call   *%rbx
mulss  0xe27(%rip),%xmm0
movss  0xc(%rsp),%xmm1
addss  %xmm1,%xmm1
addss  %xmm0,%xmm1
movss  0x14(%rsp),%xmm0
addss  %xmm1,%xmm0
add    $0x2,%ebp
cmp    %r14d,%ebp
jl     1190 <simpson+0x90>
movss  0x10(%rsp),%xmm1
mulss  %xmm0,%xmm1
divss  0xdf9(%rip),%xmm1
movaps %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

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

LLVM IR (-O2):
define float @simpson(float (...)* nocapture %0, double %1, double %2, i32 %3) {
%5 = fptrunc double %1 to float
%6 = fptrunc double %2 to float
%7 = fsub float %6, %5
%8 = sitofp i32 %3 to float
%9 = fdiv float %7, %8
%10 = fpext float %5 to double
%11 = bitcast float (...)* %0 to float (double, ...)*
%12 = tail call float (double, ...) %11(double %10)
%13 = fadd float %9, %5
%14 = fpext float %13 to double
%15 = tail call float (double, ...) %11(double %14)
%16 = tail call float @llvm.fmuladd.f32(float %15, float 4.000000e+00, float %12)
%17 = fpext float %6 to double
%18 = tail call float (double, ...) %11(double %17)
%19 = fadd float %16, %18
%20 = icmp sgt i32 %3, 2
br i1 %20, label %21, label %36
21: ; preds = %4, %21
%22 = phi float [ %33, %21 ], [ %19, %4 ]
%23 = phi i32 [ %34, %21 ], [ 2, %4 ]
%24 = sitofp i32 %23 to float
%25 = tail call float @llvm.fmuladd.f32(float %24, float %9, float %5)
%26 = fpext float %25 to double
%27 = tail call float (double, ...) %11(double %26)
%28 = fadd float %9, %25
%29 = fpext float %28 to double
%30 = tail call float (double, ...) %11(double %29)
%31 = fmul float %30, 4.000000e+00
%32 = tail call float @llvm.fmuladd.f32(float %27, float 2.000000e+00, float %31)
%33 = fadd float %22, %32
%34 = add nuw nsw i32 %23, 2
%35 = icmp slt i32 %34, %3
br i1 %35, label %21, label %36
36: ; preds = %21, %4
%37 = phi float [ %19, %4 ], [ %33, %21 ]
%38 = fmul float %9, %37
%39 = fdiv float %38, 3.000000e+00
ret float %39
}