double Graggs_Method(double (*f)(double, double), double y0, double x0,
                     double x, int number_of_steps) {
  double h = (x - x0) / (double)number_of_steps;
  double h2 = h + h;
  double y1 = y0 + h * (*f)(x0, y0);
  double y2;
  double fend;
  while (--number_of_steps) {
    x0 += h;
    y2 = y0 + h2 * (*f)(x0, y1);
    y0 = y1;
    y1 = y2;
  }
  fend = 0.5 * (y0 + y1 + h * (*f)(x, y1));
  return fend;
}


x86 assembly (clang, -O0):
<Graggs_Method>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
mov    %esi,-0x24(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
cvtsi2sdl -0x24(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x8(%rbp),%rax
movsd  -0x18(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
call   *%rax
movsd  -0x60(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x58(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
cmp    $0x0,%eax
je     11fe <Graggs_Method+0xfe>
movsd  -0x30(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x8(%rbp),%rax
movsd  -0x18(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
call   *%rax
movsd  -0x70(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x68(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1186 <Graggs_Method+0x86>
movsd  -0x10(%rbp),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
mov    -0x8(%rbp),%rax
movsd  -0x20(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
call   *%rax
movsd  -0x80(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x78(%rbp),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0xdbc(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Graggs_Method>:
push   %rbp
push   %rbx
sub    $0x38,%rsp
mov    %esi,%ebp
movaps %xmm0,%xmm3
movsd  %xmm0,0x20(%rsp)
mov    %rdi,%rbx
movsd  %xmm2,0x28(%rsp)
subsd  %xmm1,%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %esi,%xmm0
divsd  %xmm0,%xmm2
movsd  %xmm2,0x10(%rsp)
movsd  %xmm1,0x8(%rsp)
movapd %xmm1,%xmm0
movaps %xmm3,%xmm1
call   *%rdi
movsd  0x20(%rsp),%xmm2
movapd %xmm0,%xmm1
movsd  0x10(%rsp),%xmm0
mulsd  %xmm0,%xmm1
addsd  %xmm2,%xmm1
add    $0xffffffff,%ebp
je     11b7 <Graggs_Method+0xb7>
movapd %xmm0,%xmm3
addsd  %xmm0,%xmm3
movsd  %xmm3,0x30(%rsp)
movsd  0x8(%rsp),%xmm0
nop
movsd  %xmm2,0x20(%rsp)
movsd  %xmm1,0x18(%rsp)
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x8(%rsp),%xmm0
call   *%rbx
movsd  0x18(%rsp),%xmm3
movapd %xmm0,%xmm1
movsd  0x8(%rsp),%xmm0
mulsd  0x30(%rsp),%xmm1
addsd  0x20(%rsp),%xmm1
movapd %xmm3,%xmm2
add    $0xffffffff,%ebp
jne    1170 <Graggs_Method+0x70>
jmp    11bb <Graggs_Method+0xbb>
movapd %xmm2,%xmm3
addsd  %xmm1,%xmm3
movsd  %xmm3,0x18(%rsp)
movsd  0x28(%rsp),%xmm0
call   *%rbx
mulsd  0x10(%rsp),%xmm0
addsd  0x18(%rsp),%xmm0
mulsd  0xe1f(%rip),%xmm0
add    $0x38,%rsp
pop    %rbx
pop    %rbp
ret

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

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