double xfma(double x, double y, double z) {
  union {
    double f;
    long long int i;
  } tmp;
  tmp.f = x;
  tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL;
  double xh = tmp.f, xl = x - xh;
  tmp.f = y;
  tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL;
  double yh = tmp.f, yl = y - yh;
  double h = x * y;
  double l = xh * yh - h + xl * yh + xh * yl + xl * yl;
  double h2, l2, v;
  h2 = h + z;
  v = h2 - h;
  l2 = (h - (h2 - v)) + (z - v) + l;
  return h2 + l2;
}


x86 assembly (clang, -O0):
<xfma>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x4000000,%rax
and    $0xfffffffff8000000,%rax
mov    %rax,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x4000000,%rax
and    $0xfffffffff8000000,%rax
mov    %rax,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
subsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x8(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
movsd  -0x48(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
subsd  -0x68(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  -0x18(%rbp),%xmm1
subsd  -0x68(%rbp),%xmm1
addsd  %xmm1,%xmm0
addsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x58(%rbp),%xmm0
addsd  -0x60(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<xfma>:
movq   %xmm0,%rax
add    $0x4000000,%rax
and    $0xfffffffff8000000,%rax
movq   %rax,%xmm4
movdqa %xmm0,%xmm3
subsd  %xmm4,%xmm3
movq   %xmm1,%rax
add    $0x4000000,%rax
and    $0xfffffffff8000000,%rax
movq   %rax,%xmm5
mulsd  %xmm1,%xmm0
subsd  %xmm5,%xmm1
movapd %xmm4,%xmm6
mulsd  %xmm5,%xmm6
subsd  %xmm0,%xmm6
mulsd  %xmm3,%xmm5
addsd  %xmm6,%xmm5
mulsd  %xmm1,%xmm4
addsd  %xmm5,%xmm4
mulsd  %xmm1,%xmm3
addsd  %xmm4,%xmm3
movapd %xmm0,%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,%xmm4
subsd  %xmm0,%xmm4
movapd %xmm1,%xmm5
subsd  %xmm4,%xmm5
subsd  %xmm5,%xmm0
subsd  %xmm4,%xmm2
addsd  %xmm2,%xmm0
addsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
%union.anon = type { double }
define double @xfma(double %0, double %1, double %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca %union.anon
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
store double %0, double* %4
store double %1, double* %5
store double %2, double* %6
%17 = load double, double* %4
%18 = bitcast %union.anon* %7 to double*
store double %17, double* %18
%19 = bitcast %union.anon* %7 to i64*
%20 = load i64, i64* %19
%21 = add nsw i64 %20, 67108864
%22 = and i64 %21, -134217728
%23 = bitcast %union.anon* %7 to i64*
store i64 %22, i64* %23
%24 = bitcast %union.anon* %7 to double*
%25 = load double, double* %24
store double %25, double* %8
%26 = load double, double* %4
%27 = load double, double* %8
%28 = fsub double %26, %27
store double %28, double* %9
%29 = load double, double* %5
%30 = bitcast %union.anon* %7 to double*
store double %29, double* %30
%31 = bitcast %union.anon* %7 to i64*
%32 = load i64, i64* %31
%33 = add nsw i64 %32, 67108864
%34 = and i64 %33, -134217728
%35 = bitcast %union.anon* %7 to i64*
store i64 %34, i64* %35
%36 = bitcast %union.anon* %7 to double*
%37 = load double, double* %36
store double %37, double* %10
%38 = load double, double* %5
%39 = load double, double* %10
%40 = fsub double %38, %39
store double %40, double* %11
%41 = load double, double* %4
%42 = load double, double* %5
%43 = fmul double %41, %42
store double %43, double* %12
%44 = load double, double* %8
%45 = load double, double* %10
%46 = load double, double* %12
%47 = fneg double %46
%48 = call double @llvm.fmuladd.f64(double %44, double %45, double %47)
%49 = load double, double* %9
%50 = load double, double* %10
%51 = call double @llvm.fmuladd.f64(double %49, double %50, double %48)
%52 = load double, double* %8
%53 = load double, double* %11
%54 = call double @llvm.fmuladd.f64(double %52, double %53, double %51)
%55 = load double, double* %9
%56 = load double, double* %11
%57 = call double @llvm.fmuladd.f64(double %55, double %56, double %54)
store double %57, double* %13
%58 = load double, double* %12
%59 = load double, double* %6
%60 = fadd double %58, %59
store double %60, double* %14
%61 = load double, double* %14
%62 = load double, double* %12
%63 = fsub double %61, %62
store double %63, double* %16
%64 = load double, double* %12
%65 = load double, double* %14
%66 = load double, double* %16
%67 = fsub double %65, %66
%68 = fsub double %64, %67
%69 = load double, double* %6
%70 = load double, double* %16
%71 = fsub double %69, %70
%72 = fadd double %68, %71
%73 = load double, double* %13
%74 = fadd double %72, %73
store double %74, double* %15
%75 = load double, double* %14
%76 = load double, double* %15
%77 = fadd double %75, %76
ret double %77
}

LLVM IR (-O2):
define double @xfma(double %0, double %1, double %2) {
%4 = bitcast double %0 to i64
%5 = add nsw i64 %4, 67108864
%6 = and i64 %5, -134217728
%7 = bitcast i64 %6 to double
%8 = fsub double %0, %7
%9 = bitcast double %1 to i64
%10 = add nsw i64 %9, 67108864
%11 = and i64 %10, -134217728
%12 = bitcast i64 %11 to double
%13 = fsub double %1, %12
%14 = fmul double %0, %1
%15 = fneg double %14
%16 = tail call double @llvm.fmuladd.f64(double %7, double %12, double %15)
%17 = tail call double @llvm.fmuladd.f64(double %8, double %12, double %16)
%18 = tail call double @llvm.fmuladd.f64(double %7, double %13, double %17)
%19 = tail call double @llvm.fmuladd.f64(double %8, double %13, double %18)
%20 = fadd double %14, %2
%21 = fsub double %20, %14
%22 = fsub double %20, %21
%23 = fsub double %14, %22
%24 = fsub double %2, %21
%25 = fadd double %24, %23
%26 = fadd double %25, %19
%27 = fadd double %20, %26
ret double %27
}