double takFP(double x, double y, double z) {
  if (y < x)
    return takFP(takFP(x - 1.0, y, z), takFP(y - 1.0, z, x),
                 takFP(z - 1.0, x, y));
  return z;
}


x86 assembly (clang, -O0):
<takFP>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11c1 <takFP+0xb1>
movsd  -0x10(%rbp),%xmm0
movsd  0xeb8(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  -0x20(%rbp),%xmm2
call   1030 <takFP@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe93(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm2
call   1030 <takFP@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe6e(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm2
call   1030 <takFP@plt>
movsd  -0x30(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x28(%rbp),%xmm0
call   1030 <takFP@plt>
movsd  %xmm0,-0x8(%rbp)
jmp    11cb <takFP+0xbb>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<takFP>:
sub    $0x28,%rsp
ucomisd %xmm1,%xmm0
jbe    11b8 <takFP+0xa8>
movapd %xmm1,%xmm3
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  %xmm3,0x8(%rsp)
movsd  %xmm0,0x10(%rsp)
movsd  0xebc(%rip),%xmm1
addsd  %xmm1,%xmm0
movapd %xmm3,%xmm1
movsd  %xmm2,(%rsp)
call   1030 <takFP@plt>
movsd  %xmm0,0x20(%rsp)
movsd  0x8(%rsp),%xmm0
addsd  0xe96(%rip),%xmm0
movsd  (%rsp),%xmm1
movsd  0x10(%rsp),%xmm2
call   1030 <takFP@plt>
movsd  %xmm0,0x18(%rsp)
movsd  (%rsp),%xmm0
addsd  0xe73(%rip),%xmm0
movsd  0x10(%rsp),%xmm1
movsd  0x8(%rsp),%xmm2
call   1030 <takFP@plt>
movapd %xmm0,%xmm2
movsd  0x20(%rsp),%xmm0
movsd  0x18(%rsp),%xmm3
ucomisd %xmm3,%xmm0
ja     1130 <takFP+0x20>
movapd %xmm2,%xmm0
add    $0x28,%rsp
ret

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

LLVM IR (-O2):
define double @takFP(double %0, double %1, double %2) {
%4 = fcmp olt double %1, %0
br i1 %4, label %5, label %16
5: ; preds = %3, %5
%6 = phi double [ %14, %5 ], [ %2, %3 ]
%7 = phi double [ %12, %5 ], [ %1, %3 ]
%8 = phi double [ %10, %5 ], [ %0, %3 ]
%9 = fadd double %8, -1.000000e+00
%10 = tail call double @takFP(double %9, double %7, double %6)
%11 = fadd double %7, -1.000000e+00
%12 = tail call double @takFP(double %11, double %6, double %8)
%13 = fadd double %6, -1.000000e+00
%14 = tail call double @takFP(double %13, double %8, double %7)
%15 = fcmp olt double %12, %10
br i1 %15, label %5, label %16
16: ; preds = %5, %3
%17 = phi double [ %2, %3 ], [ %14, %5 ]
ret double %17
}