double rk4(double (*f)(double, double), double dt, double x, double dx) {
  double k1 = dt * f(x, dx), k2 = dt * f(x + dt / 2, dx + k1 / 2),
         k3 = dt * f(x + dt / 2, dx + k2 / 2), k4 = dt * f(x + dt, dx + k3);
  return dx + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
}


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

x86 assembly (clang, -O2):
<rk4>:
push   %rbx
sub    $0x30,%rsp
movsd  %xmm2,0x8(%rsp)
movsd  %xmm1,0x18(%rsp)
movsd  %xmm0,(%rsp)
mov    %rdi,%rbx
movapd %xmm1,%xmm0
movaps %xmm2,%xmm1
call   *%rdi
movsd  (%rsp),%xmm2
mulsd  %xmm2,%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0xec7(%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  0xe90(%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
divsd  0xe2e(%rip),%xmm0
addsd  0x8(%rsp),%xmm0
add    $0x30,%rsp
pop    %rbx
ret

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

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