double sqrt(double x) {
  double ret = x;
  int i;
  for (i = 0; i < 10; i++)
    ret = (ret * ret + x) / (ret * 2.0);
  return ret;
}


x86 assembly (clang, -O0):
<sqrt>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0xa,-0x14(%rbp)
jge    115f <sqrt+0x5f>
movsd  -0x10(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm2
movsd  -0x8(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xebd(%rip),%xmm1
mulsd  -0x10(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    111a <sqrt+0x1a>
movsd  -0x10(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<sqrt>:
movapd %xmm0,%xmm1
mulsd  %xmm0,%xmm1
addsd  %xmm0,%xmm1
movapd %xmm0,%xmm2
addsd  %xmm0,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
addsd  %xmm1,%xmm1
divsd  %xmm1,%xmm2
movapd %xmm2,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
addsd  %xmm2,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
addsd  %xmm1,%xmm1
divsd  %xmm1,%xmm2
movapd %xmm2,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
addsd  %xmm2,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
addsd  %xmm1,%xmm1
divsd  %xmm1,%xmm2
movapd %xmm2,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
addsd  %xmm2,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
addsd  %xmm1,%xmm1
divsd  %xmm1,%xmm2
movapd %xmm2,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
addsd  %xmm2,%xmm2
divsd  %xmm2,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm2,%xmm0
addsd  %xmm1,%xmm1
divsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @sqrt(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca i32
store double %0, double* %2
%5 = load double, double* %2
store double %5, double* %3
store i32 0, i32* %4
br label %6
6: ; preds = %17, %1
%7 = load i32, i32* %4
%8 = icmp slt i32 %7, 10
br i1 %8, label %9, label %20
9: ; preds = %6
%10 = load double, double* %3
%11 = load double, double* %3
%12 = load double, double* %2
%13 = call double @llvm.fmuladd.f64(double %10, double %11, double %12)
%14 = load double, double* %3
%15 = fmul double %14, 2.000000e+00
%16 = fdiv double %13, %15
store double %16, double* %3
br label %17
17: ; preds = %9
%18 = load i32, i32* %4
%19 = add nsw i32 %18, 1
store i32 %19, i32* %4
br label %6
20: ; preds = %6
%21 = load double, double* %3
ret double %21
}

LLVM IR (-O2):
define double @sqrt(double %0) {
%2 = tail call double @llvm.fmuladd.f64(double %0, double %0, double %0)
%3 = fmul double %0, 2.000000e+00
%4 = fdiv double %2, %3
%5 = tail call double @llvm.fmuladd.f64(double %4, double %4, double %0)
%6 = fmul double %4, 2.000000e+00
%7 = fdiv double %5, %6
%8 = tail call double @llvm.fmuladd.f64(double %7, double %7, double %0)
%9 = fmul double %7, 2.000000e+00
%10 = fdiv double %8, %9
%11 = tail call double @llvm.fmuladd.f64(double %10, double %10, double %0)
%12 = fmul double %10, 2.000000e+00
%13 = fdiv double %11, %12
%14 = tail call double @llvm.fmuladd.f64(double %13, double %13, double %0)
%15 = fmul double %13, 2.000000e+00
%16 = fdiv double %14, %15
%17 = tail call double @llvm.fmuladd.f64(double %16, double %16, double %0)
%18 = fmul double %16, 2.000000e+00
%19 = fdiv double %17, %18
%20 = tail call double @llvm.fmuladd.f64(double %19, double %19, double %0)
%21 = fmul double %19, 2.000000e+00
%22 = fdiv double %20, %21
%23 = tail call double @llvm.fmuladd.f64(double %22, double %22, double %0)
%24 = fmul double %22, 2.000000e+00
%25 = fdiv double %23, %24
%26 = tail call double @llvm.fmuladd.f64(double %25, double %25, double %0)
%27 = fmul double %25, 2.000000e+00
%28 = fdiv double %26, %27
%29 = tail call double @llvm.fmuladd.f64(double %28, double %28, double %0)
%30 = fmul double %28, 2.000000e+00
%31 = fdiv double %29, %30
ret double %31
}