double solve_fp(f, x0, tol, maxit) double (*f)(), x0, tol;
int maxit;
{
  double x1;
  int i;
  for (i = 0; i < maxit; i++) {
    x1 = f(x0);
    if (fabs(x1 - x0) < tol)
      return (x1);
    x0 = x1;
  }
  return (x1);
}


x86 assembly (clang, -O0):
<solve_fp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %esi,-0x24(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1189 <solve_fp+0x89>
mov    -0x10(%rbp),%rcx
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
call   *%rcx
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm1
subsd  -0x18(%rbp),%xmm1
movaps 0xeb1(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  -0x20(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1171 <solve_fp+0x71>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1193 <solve_fp+0x93>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1120 <solve_fp+0x20>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<solve_fp>:
push   %rbp
push   %r14
push   %rbx
sub    $0x10,%rsp
movsd  %xmm1,(%rsp)
test   %esi,%esi
jle    1153 <solve_fp+0x53>
mov    %esi,%r14d
mov    %rdi,%rbx
mov    $0x1,%ebp
nopl   0x0(%rax)
movsd  %xmm0,0x8(%rsp)
mov    $0x1,%al
call   *%rbx
movapd %xmm0,%xmm1
subsd  0x8(%rsp),%xmm1
andpd  0xec4(%rip),%xmm1
movsd  (%rsp),%xmm2
ucomisd %xmm1,%xmm2
ja     1153 <solve_fp+0x53>
lea    0x1(%rbp),%eax
cmp    %r14d,%ebp
mov    %eax,%ebp
jl     1120 <solve_fp+0x20>
jmp    1153 <solve_fp+0x53>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define double @solve_fp(double (...)* %0, double %1, double %2, i32 %3) {
%5 = alloca double
%6 = alloca double (...)*
%7 = alloca double
%8 = alloca double
%9 = alloca i32
%10 = alloca double
%11 = alloca i32
store double (...)* %0, double (...)** %6
store double %1, double* %7
store double %2, double* %8
store i32 %3, i32* %9
store i32 0, i32* %11
br label %12
12: ; preds = %31, %4
%13 = load i32, i32* %11
%14 = load i32, i32* %9
%15 = icmp slt i32 %13, %14
br i1 %15, label %16, label %34
16: ; preds = %12
%17 = load double (...)*, double (...)** %6
%18 = load double, double* %7
%19 = bitcast double (...)* %17 to double (double, ...)*
%20 = call double (double, ...) %19(double %18)
store double %20, double* %10
%21 = load double, double* %10
%22 = load double, double* %7
%23 = fsub double %21, %22
%24 = call double @llvm.fabs.f64(double %23)
%25 = load double, double* %8
%26 = fcmp olt double %24, %25
br i1 %26, label %27, label %29
27: ; preds = %16
%28 = load double, double* %10
store double %28, double* %5
br label %36
29: ; preds = %16
%30 = load double, double* %10
store double %30, double* %7
br label %31
31: ; preds = %29
%32 = load i32, i32* %11
%33 = add nsw i32 %32, 1
store i32 %33, i32* %11
br label %12
34: ; preds = %12
%35 = load double, double* %10
store double %35, double* %5
br label %36
36: ; preds = %34, %27
%37 = load double, double* %5
ret double %37
}

LLVM IR (-O2):
define double @solve_fp(double (...)* nocapture %0, double %1, double %2, i32 %3) {
%5 = bitcast double (...)* %0 to double (double, ...)*
%6 = icmp sgt i32 %3, 0
br i1 %6, label %7, label %17
7: ; preds = %4, %7
%8 = phi i32 [ %14, %7 ], [ 0, %4 ]
%9 = phi double [ %10, %7 ], [ %1, %4 ]
%10 = tail call double (double, ...) %5(double %9)
%11 = fsub double %10, %9
%12 = tail call double @llvm.fabs.f64(double %11)
%13 = fcmp uge double %12, %2
%14 = add nuw nsw i32 %8, 1
%15 = icmp slt i32 %14, %3
%16 = select i1 %13, i1 %15, i1 false
br i1 %16, label %7, label %17
17: ; preds = %7, %4
%18 = phi double [ undef, %4 ], [ %10, %7 ]
ret double %18
}