#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double __builtin_inf();
int doubleToRawLongBits(double);
double longBitsToDouble(int);
double xfma(double, double, double);
double xsqrt(double d) {
  double q = 1;
  if (d < 8.636168555094445E-78) {
    d *= 1.157920892373162E77;
    q = 2.9387358770557188E-39;
  }
  double x = longBitsToDouble(0x5fe6ec85e7de30da -
                              (doubleToRawLongBits(d + 1e-320) >> 1));
  x = x * (1.5 - 0.5 * d * x * x);
  x = x * (1.5 - 0.5 * d * x * x);
  x = x * (1.5 - 0.5 * d * x * x);
  x = xfma(d * x, d * x, -d) * (x * -0.5) + d * x;
  return d == __builtin_inf() ? __builtin_inf() : x * q;
}


x86 assembly (clang, -O0):
<xsqrt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  0xec3(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xeae(%rip),%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    117c <xsqrt+0x4c>
movsd  0xeb3(%rip),%xmm0
mulsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  0xe99(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xebc(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
call   1040 <doubleToRawLongBits@plt>
sar    $0x1,%eax
movslq %eax,%rcx
movabs $0x5fe6ec85e7de30da,%rax
ec e6 5f
sub    %rcx,%rax
mov    %eax,%edi
call   1030 <longBitsToDouble@plt>
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe7e(%rip),%xmm1
mulsd  -0x8(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xe44(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe32(%rip),%xmm1
mulsd  -0x8(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xdf8(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xde6(%rip),%xmm1
mulsd  -0x8(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xdac(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x8(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
movsd  -0x8(%rbp),%xmm2
movq   %xmm2,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm2
call   1050 <xfma@plt>
movsd  0xd5a(%rip),%xmm2
mulsd  -0x18(%rbp),%xmm2
movsd  -0x8(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xd29(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1319 <xsqrt+0x1e9>
jp     1319 <xsqrt+0x1e9>
movsd  0xd11(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1328 <xsqrt+0x1f8>
movsd  -0x18(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<xsqrt>:
push   %rbp
push   %rbx
sub    $0x38,%rsp
movapd %xmm0,%xmm1
movsd  0xebe(%rip),%xmm0
xor    %ebx,%ebx
ucomisd %xmm1,%xmm0
seta   %bpl
jbe    1156 <xsqrt+0x26>
mulsd  0xeb2(%rip),%xmm1
movapd %xmm1,(%rsp)
movsd  0xead(%rip),%xmm0
addsd  %xmm1,%xmm0
call   1040 <doubleToRawLongBits@plt>
sar    %eax
mov    $0xe7de30da,%edi
sub    %eax,%edi
call   1030 <longBitsToDouble@plt>
movapd (%rsp),%xmm4
movapd %xmm4,%xmm3
mulsd  0xe8d(%rip),%xmm3
movapd %xmm3,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm0,%xmm1
movsd  0xe81(%rip),%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm3,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
addsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm3
mulsd  %xmm0,%xmm3
addsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm3
movapd %xmm3,0x20(%rsp)
movapd %xmm4,%xmm1
mulsd  %xmm3,%xmm1
movapd %xmm1,0x10(%rsp)
movapd 0xe49(%rip),%xmm2
xorpd  %xmm4,%xmm2
movapd %xmm1,%xmm0
call   1050 <xfma@plt>
movapd 0x20(%rsp),%xmm1
mulsd  0xe16(%rip),%xmm1
mulsd  %xmm0,%xmm1
addsd  0x10(%rsp),%xmm1
mov    %bpl,%bl
lea    0xe2a(%rip),%rax
mulsd  (%rax,%rbx,8),%xmm1
movapd %xmm1,%xmm3
movsd  0xe01(%rip),%xmm1
movapd %xmm1,%xmm0
cmplesd (%rsp),%xmm0
movapd %xmm0,%xmm2
andnpd %xmm3,%xmm2
andpd  %xmm1,%xmm0
orpd   %xmm2,%xmm0
add    $0x38,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define double @xsqrt(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
store double %0, double* %2
store double 1.000000e+00, double* %3
%5 = load double, double* %2
%6 = fcmp olt double %5, 0x2FF0000000000000
br i1 %6, label %7, label %10
7: ; preds = %1
%8 = load double, double* %2
%9 = fmul double %8, 0x4FF0000000000000
store double %9, double* %2
store double 0x37F0000000000000, double* %3
br label %10
10: ; preds = %7, %1
%11 = load double, double* %2
%12 = fadd double %11, 9.999880e-321
%13 = call i32 @doubleToRawLongBits(double %12)
%14 = ashr i32 %13, 1
%15 = sext i32 %14 to i64
%16 = sub nsw i64 6910470738111508698, %15
%17 = trunc i64 %16 to i32
%18 = call double @longBitsToDouble(i32 %17)
store double %18, double* %4
%19 = load double, double* %4
%20 = load double, double* %2
%21 = fmul double 5.000000e-01, %20
%22 = load double, double* %4
%23 = fmul double %21, %22
%24 = load double, double* %4
%25 = fneg double %23
%26 = call double @llvm.fmuladd.f64(double %25, double %24, double 1.500000e+00)
%27 = fmul double %19, %26
store double %27, double* %4
%28 = load double, double* %4
%29 = load double, double* %2
%30 = fmul double 5.000000e-01, %29
%31 = load double, double* %4
%32 = fmul double %30, %31
%33 = load double, double* %4
%34 = fneg double %32
%35 = call double @llvm.fmuladd.f64(double %34, double %33, double 1.500000e+00)
%36 = fmul double %28, %35
store double %36, double* %4
%37 = load double, double* %4
%38 = load double, double* %2
%39 = fmul double 5.000000e-01, %38
%40 = load double, double* %4
%41 = fmul double %39, %40
%42 = load double, double* %4
%43 = fneg double %41
%44 = call double @llvm.fmuladd.f64(double %43, double %42, double 1.500000e+00)
%45 = fmul double %37, %44
store double %45, double* %4
%46 = load double, double* %2
%47 = load double, double* %4
%48 = fmul double %46, %47
%49 = load double, double* %2
%50 = load double, double* %4
%51 = fmul double %49, %50
%52 = load double, double* %2
%53 = fneg double %52
%54 = call double @xfma(double %48, double %51, double %53)
%55 = load double, double* %4
%56 = fmul double %55, -5.000000e-01
%57 = load double, double* %2
%58 = load double, double* %4
%59 = fmul double %57, %58
%60 = call double @llvm.fmuladd.f64(double %54, double %56, double %59)
store double %60, double* %4
%61 = load double, double* %2
%62 = fcmp oeq double %61, 0x7FF0000000000000
br i1 %62, label %63, label %64
63: ; preds = %10
br label %68
64: ; preds = %10
%65 = load double, double* %4
%66 = load double, double* %3
%67 = fmul double %65, %66
br label %68
68: ; preds = %64, %63
%69 = phi double [ 0x7FF0000000000000, %63 ], [ %67, %64 ]
ret double %69
}

LLVM IR (-O2):
define double @xsqrt(double %0) {
%2 = fcmp olt double %0, 0x2FF0000000000000
%3 = fmul double %0, 0x4FF0000000000000
%4 = select i1 %2, double 0x37F0000000000000, double 1.000000e+00
%5 = select i1 %2, double %3, double %0
%6 = fadd double %5, 9.999880e-321
%7 = tail call i32 @doubleToRawLongBits(double %6)
%8 = ashr i32 %7, 1
%9 = sub nsw i32 -404868902, %8
%10 = tail call double @longBitsToDouble(i32 %9)
%11 = fmul double %5, -5.000000e-01
%12 = fmul double %11, %10
%13 = tail call double @llvm.fmuladd.f64(double %12, double %10, double 1.500000e+00)
%14 = fmul double %10, %13
%15 = fmul double %11, %14
%16 = tail call double @llvm.fmuladd.f64(double %15, double %14, double 1.500000e+00)
%17 = fmul double %14, %16
%18 = fmul double %11, %17
%19 = tail call double @llvm.fmuladd.f64(double %18, double %17, double 1.500000e+00)
%20 = fmul double %17, %19
%21 = fmul double %5, %20
%22 = fneg double %5
%23 = tail call double @xfma(double %21, double %21, double %22)
%24 = fmul double %20, -5.000000e-01
%25 = tail call double @llvm.fmuladd.f64(double %23, double %24, double %21)
%26 = fcmp oeq double %5, 0x7FF0000000000000
%27 = fmul double %4, %25
%28 = select i1 %26, double 0x7FF0000000000000, double %27
ret double %28
}