double RK4(double x, double y, double h, double (*F)(double, double)) {
  int i;
  double ynew, k[4];
  k[0] = h * F(x, y);
  k[1] = h * F(x + 0.5 * h, y + 0.5 * k[0]);
  k[2] = h * F(x + 0.5 * h, y + 0.5 * k[1]);
  k[3] = h * F(x + h, y + k[2]);
  ynew = y + (1.0 / 6.0) * (k[0] + 2 * k[1] + 2 * k[2] + k[3]);
  return ynew;
}


x86 assembly (clang, -O0):
<RK4>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
mov    %rdi,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
call   *%rax
movaps %xmm0,%xmm1
movsd  -0x70(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
movsd  0xea2(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm2
movsd  -0x50(%rbp),%xmm1
movsd  0xe88(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
call   *%rax
movaps %xmm0,%xmm1
movsd  -0x68(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm0
movsd  0xe4d(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm1
movsd  0xe33(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
call   *%rax
movaps %xmm0,%xmm1
movsd  -0x60(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
addsd  -0x40(%rbp),%xmm1
call   *%rax
movaps %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
addsd  %xmm2,%xmm2
addsd  %xmm0,%xmm2
movsd  -0x40(%rbp),%xmm0
addsd  %xmm0,%xmm0
addsd  %xmm2,%xmm0
addsd  -0x38(%rbp),%xmm0
movsd  0xdaa(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<RK4>:
push   %rbx
sub    $0x30,%rsp
mov    %rdi,%rbx
movsd  %xmm2,(%rsp)
movsd  %xmm1,0x8(%rsp)
movsd  %xmm0,0x18(%rsp)
call   *%rdi
movsd  (%rsp),%xmm2
mulsd  %xmm2,%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0xece(%rip),%xmm3
mulsd  %xmm3,%xmm2
addsd  0x18(%rsp),%xmm2
movsd  %xmm2,0x10(%rsp)
movapd %xmm0,%xmm1
mulsd  %xmm3,%xmm1
addsd  0x8(%rsp),%xmm1
movapd %xmm2,%xmm0
call   *%rbx
mulsd  (%rsp),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0xe97(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0x8(%rsp),%xmm1
movsd  0x10(%rsp),%xmm0
call   *%rbx
movapd %xmm0,%xmm2
movsd  (%rsp),%xmm1
mulsd  %xmm1,%xmm2
movsd  %xmm2,0x10(%rsp)
movsd  0x18(%rsp),%xmm0
addsd  %xmm1,%xmm0
addsd  0x8(%rsp),%xmm2
movapd %xmm2,%xmm1
call   *%rbx
mulsd  (%rsp),%xmm0
movsd  0x20(%rsp),%xmm1
addsd  %xmm1,%xmm1
addsd  0x28(%rsp),%xmm1
movsd  0x10(%rsp),%xmm2
addsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
addsd  %xmm2,%xmm0
mulsd  0xe35(%rip),%xmm0
addsd  0x8(%rsp),%xmm0
add    $0x30,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @RK4(double %0, double %1, double %2, double (double, double)* %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double (double, double)*
%9 = alloca i32
%10 = alloca double
%11 = alloca [4 x double]
store double %0, double* %5
store double %1, double* %6
store double %2, double* %7
store double (double, double)* %3, double (double, double)** %8
%12 = load double, double* %7
%13 = load double (double, double)*, double (double, double)** %8
%14 = load double, double* %5
%15 = load double, double* %6
%16 = call double %13(double %14, double %15)
%17 = fmul double %12, %16
%18 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 0
store double %17, double* %18
%19 = load double, double* %7
%20 = load double (double, double)*, double (double, double)** %8
%21 = load double, double* %5
%22 = load double, double* %7
%23 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %22, double %21)
%24 = load double, double* %6
%25 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 0
%26 = load double, double* %25
%27 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %26, double %24)
%28 = call double %20(double %23, double %27)
%29 = fmul double %19, %28
%30 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 1
store double %29, double* %30
%31 = load double, double* %7
%32 = load double (double, double)*, double (double, double)** %8
%33 = load double, double* %5
%34 = load double, double* %7
%35 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %34, double %33)
%36 = load double, double* %6
%37 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 1
%38 = load double, double* %37
%39 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %38, double %36)
%40 = call double %32(double %35, double %39)
%41 = fmul double %31, %40
%42 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 2
store double %41, double* %42
%43 = load double, double* %7
%44 = load double (double, double)*, double (double, double)** %8
%45 = load double, double* %5
%46 = load double, double* %7
%47 = fadd double %45, %46
%48 = load double, double* %6
%49 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 2
%50 = load double, double* %49
%51 = fadd double %48, %50
%52 = call double %44(double %47, double %51)
%53 = fmul double %43, %52
%54 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 3
store double %53, double* %54
%55 = load double, double* %6
%56 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 0
%57 = load double, double* %56
%58 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 1
%59 = load double, double* %58
%60 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %59, double %57)
%61 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 2
%62 = load double, double* %61
%63 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %62, double %60)
%64 = getelementptr inbounds [4 x double], [4 x double]* %11, i64 0, i64 3
%65 = load double, double* %64
%66 = fadd double %63, %65
%67 = call double @llvm.fmuladd.f64(double 0x3FC5555555555555, double %66, double %55)
store double %67, double* %10
%68 = load double, double* %10
ret double %68
}

LLVM IR (-O2):
define double @RK4(double %0, double %1, double %2, double (double, double)* nocapture %3) {
%5 = tail call double %3(double %0, double %1)
%6 = fmul double %5, %2
%7 = tail call double @llvm.fmuladd.f64(double %2, double 5.000000e-01, double %0)
%8 = tail call double @llvm.fmuladd.f64(double %6, double 5.000000e-01, double %1)
%9 = tail call double %3(double %7, double %8)
%10 = fmul double %9, %2
%11 = tail call double @llvm.fmuladd.f64(double %10, double 5.000000e-01, double %1)
%12 = tail call double %3(double %7, double %11)
%13 = fmul double %12, %2
%14 = fadd double %0, %2
%15 = fadd double %13, %1
%16 = tail call double %3(double %14, double %15)
%17 = fmul double %16, %2
%18 = tail call double @llvm.fmuladd.f64(double %10, double 2.000000e+00, double %6)
%19 = tail call double @llvm.fmuladd.f64(double %13, double 2.000000e+00, double %18)
%20 = fadd double %19, %17
%21 = tail call double @llvm.fmuladd.f64(double %20, double 0x3FC5555555555555, double %1)
ret double %21
}