int euclideanGCD(double a, double b, double *f) {
  if (a == 0) {
    *f = b;
    return 0;
  }
  while (b != 0) {
    if (a > b) {
      a = a - b;
    } else {
      b = b - a;
    }
  }
  *f = a;
  return 0;
}


x86 assembly (clang, -O0):
<euclideanGCD>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rdi,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1143 <euclideanGCD+0x43>
jp     1143 <euclideanGCD+0x43>
movsd  -0x18(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x0,-0x4(%rbp)
jmp    11b1 <euclideanGCD+0xb1>
jmp    1148 <euclideanGCD+0x48>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1165 <euclideanGCD+0x65>
jp     1165 <euclideanGCD+0x65>
jmp    119d <euclideanGCD+0x9d>
movsd  -0x10(%rbp),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    1189 <euclideanGCD+0x89>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    1198 <euclideanGCD+0x98>
movsd  -0x18(%rbp),%xmm0
subsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    1148 <euclideanGCD+0x48>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<euclideanGCD>:
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm0
jne    1117 <euclideanGCD+0x17>
jp     1117 <euclideanGCD+0x17>
movapd %xmm1,%xmm0
movsd  %xmm0,(%rdi)
xor    %eax,%eax
ret
ucomisd %xmm2,%xmm1
jne    111f <euclideanGCD+0x1f>
jnp    1110 <euclideanGCD+0x10>
xorpd  %xmm2,%xmm2
jmp    114d <euclideanGCD+0x4d>
cs nopw 0x0(%rax,%rax,1)
nop
movapd %xmm1,%xmm4
cmpltsd %xmm0,%xmm4
andpd  %xmm1,%xmm4
subsd  %xmm4,%xmm0
subsd  %xmm3,%xmm1
ucomisd %xmm2,%xmm1
jne    114d <euclideanGCD+0x4d>
jnp    1110 <euclideanGCD+0x10>
ucomisd %xmm1,%xmm0
xorpd  %xmm3,%xmm3
ja     1130 <euclideanGCD+0x30>
movapd %xmm0,%xmm3
jmp    1130 <euclideanGCD+0x30>

LLVM IR (-O0):
define i32 @euclideanGCD(double %0, double %1, double* %2) {
%4 = alloca i32
%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* %5
%9 = fcmp oeq double %8, 0.000000e+00
br i1 %9, label %10, label %13
10: ; preds = %3
%11 = load double, double* %6
%12 = load double*, double** %7
store double %11, double* %12
store i32 0, i32* %4
br label %33
13: ; preds = %3
br label %14
14: ; preds = %29, %13
%15 = load double, double* %6
%16 = fcmp une double %15, 0.000000e+00
br i1 %16, label %17, label %30
17: ; preds = %14
%18 = load double, double* %5
%19 = load double, double* %6
%20 = fcmp ogt double %18, %19
br i1 %20, label %21, label %25
21: ; preds = %17
%22 = load double, double* %5
%23 = load double, double* %6
%24 = fsub double %22, %23
store double %24, double* %5
br label %29
25: ; preds = %17
%26 = load double, double* %6
%27 = load double, double* %5
%28 = fsub double %26, %27
store double %28, double* %6
br label %29
29: ; preds = %25, %21
br label %14
30: ; preds = %14
%31 = load double, double* %5
%32 = load double*, double** %7
store double %31, double* %32
store i32 0, i32* %4
br label %33
33: ; preds = %30, %10
%34 = load i32, i32* %4
ret i32 %34
}

LLVM IR (-O2):
define i32 @euclideanGCD(double %0, double %1, double* nocapture writeonly %2) {
%4 = fcmp oeq double %0, 0.000000e+00
br i1 %4, label %16, label %5
5: ; preds = %3
%6 = fcmp une double %1, 0.000000e+00
br i1 %6, label %7, label %16
7: ; preds = %5, %7
%8 = phi double [ %14, %7 ], [ %1, %5 ]
%9 = phi double [ %12, %7 ], [ %0, %5 ]
%10 = fcmp ogt double %9, %8
%11 = select i1 %10, double %8, double 0.000000e+00
%12 = fsub double %9, %11
%13 = select i1 %10, double 0.000000e+00, double %9
%14 = fsub double %8, %13
%15 = fcmp une double %14, 0.000000e+00
br i1 %15, label %7, label %16
16: ; preds = %7, %5, %3
%17 = phi double [ %1, %3 ], [ %0, %5 ], [ %12, %7 ]
store double %17, double* %2
ret i32 0
}