double ft_sqrt(double n) {
  double a;
  double b;
  double cache;
  if (n == 0)
    return (0);
  if (n < 0)
    return (-1);
  a = n / 2;
  cache = a;
  while (1) {
    b = n / a;
    a = (a + b) / 2;
    if (a - cache == 0)
      return (a);
    cache = a;
  }
  return (-1);
}


x86 assembly (clang, -O0):
<ft_sqrt>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    112e <ft_sqrt+0x2e>
jp     112e <ft_sqrt+0x2e>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <ft_sqrt+0xd3>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    114e <ft_sqrt+0x4e>
movsd  0xec4(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <ft_sqrt+0xd3>
movsd  -0x10(%rbp),%xmm0
movsd  0xea5(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  0xe71(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11c4 <ft_sqrt+0xc4>
jp     11c4 <ft_sqrt+0xc4>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <ft_sqrt+0xd3>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    116e <ft_sqrt+0x6e>
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<ft_sqrt>:
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    110c <ft_sqrt+0xc>
jnp    1164 <ft_sqrt+0x64>
xorpd  %xmm2,%xmm2
ucomisd %xmm0,%xmm2
jbe    111f <ft_sqrt+0x1f>
movsd  0xee2(%rip),%xmm0
ret
movsd  0xee1(%rip),%xmm3
mulsd  %xmm0,%xmm3
movsd  0xed5(%rip),%xmm4
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movapd %xmm0,%xmm1
divsd  %xmm3,%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm4,%xmm1
movapd %xmm1,%xmm5
subsd  %xmm3,%xmm5
ucomisd %xmm2,%xmm5
movapd %xmm1,%xmm3
jne    1140 <ft_sqrt+0x40>
jp     1140 <ft_sqrt+0x40>
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @ft_sqrt(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
store double %0, double* %3
%7 = load double, double* %3
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %9, label %10
9: ; preds = %1
store double 0.000000e+00, double* %2
br label %34
10: ; preds = %1
%11 = load double, double* %3
%12 = fcmp olt double %11, 0.000000e+00
br i1 %12, label %13, label %14
13: ; preds = %10
store double -1.000000e+00, double* %2
br label %34
14: ; preds = %10
%15 = load double, double* %3
%16 = fdiv double %15, 2.000000e+00
store double %16, double* %4
%17 = load double, double* %4
store double %17, double* %6
br label %18
18: ; preds = %14, %32
%19 = load double, double* %3
%20 = load double, double* %4
%21 = fdiv double %19, %20
store double %21, double* %5
%22 = load double, double* %4
%23 = load double, double* %5
%24 = fadd double %22, %23
%25 = fdiv double %24, 2.000000e+00
store double %25, double* %4
%26 = load double, double* %4
%27 = load double, double* %6
%28 = fsub double %26, %27
%29 = fcmp oeq double %28, 0.000000e+00
br i1 %29, label %30, label %32
30: ; preds = %18
%31 = load double, double* %4
store double %31, double* %2
br label %34
32: ; preds = %18
%33 = load double, double* %4
store double %33, double* %6
br label %18
34: ; preds = %30, %13, %9
%35 = load double, double* %2
ret double %35
}

LLVM IR (-O2):
define double @ft_sqrt(double %0) {
%2 = fcmp oeq double %0, 0.000000e+00
br i1 %2, label %14, label %3
3: ; preds = %1
%4 = fcmp olt double %0, 0.000000e+00
br i1 %4, label %14, label %5
5: ; preds = %3
%6 = fmul double %0, 5.000000e-01
br label %7
7: ; preds = %7, %5
%8 = phi double [ %6, %5 ], [ %11, %7 ]
%9 = fdiv double %0, %8
%10 = fadd double %8, %9
%11 = fmul double %10, 5.000000e-01
%12 = fsub double %11, %8
%13 = fcmp oeq double %12, 0.000000e+00
br i1 %13, label %14, label %7
14: ; preds = %7, %3, %1
%15 = phi double [ 0.000000e+00, %1 ], [ -1.000000e+00, %3 ], [ %11, %7 ]
ret double %15
}