double random_unit_gaussian(void) {
  double r, u, v, fac;
  static _Bool set = (0 != 0);
  static double dset;
  if (set) {
    set = (0 != 0);
    return dset;
  }
  do {
    u = 2.0 * random_unit_uniform() - 1.0;
    v = 2.0 * random_unit_uniform() - 1.0;
    r = u * u + v * v;
  } while (r >= 1.0);
  fac = sqrt(-2.0 * log(r) / r);
  dset = v * fac;
  return u * fac;
}


x86 assembly (clang, -O0):
<random_unit_gaussian>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
testb  $0x1,0x2f01(%rip)
je     115e <random_unit_gaussian+0x2e>
movb   $0x0,0x2ef4(%rip)
movsd  0x2ef4(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1224 <random_unit_gaussian+0xf4>
jmp    1163 <random_unit_gaussian+0x33>
mov    $0x0,%al
call   1030 <random_unit_uniform@plt>
cvtsi2sd %eax,%xmm0
addsd  %xmm0,%xmm0
movsd  0xe86(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    $0x0,%al
call   1030 <random_unit_uniform@plt>
cvtsi2sd %eax,%xmm0
addsd  %xmm0,%xmm0
movsd  0xe66(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm2
movsd  -0x20(%rbp),%xmm1
mulsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xe37(%rip),%xmm1
ucomisd %xmm1,%xmm0
jae    1163 <random_unit_gaussian+0x33>
movsd  -0x10(%rbp),%xmm0
call   1040 <log@plt>
movaps %xmm0,%xmm1
movsd  0xe20(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x10(%rbp),%xmm0
call   1050 <sqrt@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,0x2e33(%rip)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<random_unit_gaussian>:
sub    $0x18,%rsp
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
xor    %eax,%eax
call   1030 <random_unit_uniform@plt>
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
addsd  %xmm1,%xmm1
movsd  0xea6(%rip),%xmm0
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
xor    %eax,%eax
call   1030 <random_unit_uniform@plt>
movsd  0x8(%rsp),%xmm0
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
addsd  %xmm2,%xmm2
addsd  0xe7c(%rip),%xmm2
mulsd  %xmm2,%xmm2
mulsd  %xmm0,%xmm0
addsd  %xmm2,%xmm0
ucomisd 0xe70(%rip),%xmm0
jae    1140 <random_unit_gaussian+0x10>
movsd  %xmm0,0x10(%rsp)
call   1040 <log@plt>
mulsd  0xe63(%rip),%xmm0
divsd  0x10(%rsp),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     11c3 <random_unit_gaussian+0x93>
sqrtsd %xmm0,%xmm0
jmp    11c8 <random_unit_gaussian+0x98>
call   1050 <sqrt@plt>
movsd  0x8(%rsp),%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
@random_unit_gaussian.set = internal global i8 0
@random_unit_gaussian.dset = internal global double 0.000000e+00
define double @random_unit_gaussian() {
%1 = alloca double
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = load i8, i8* @random_unit_gaussian.set
%7 = trunc i8 %6 to i1
br i1 %7, label %8, label %10
8: ; preds = %0
store i8 0, i8* @random_unit_gaussian.set
%9 = load double, double* @random_unit_gaussian.dset
store double %9, double* %1
br label %40
10: ; preds = %0
br label %11
11: ; preds = %24, %10
%12 = call i32 (...) @random_unit_uniform()
%13 = sitofp i32 %12 to double
%14 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %13, double -1.000000e+00)
store double %14, double* %3
%15 = call i32 (...) @random_unit_uniform()
%16 = sitofp i32 %15 to double
%17 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %16, double -1.000000e+00)
store double %17, double* %4
%18 = load double, double* %3
%19 = load double, double* %3
%20 = load double, double* %4
%21 = load double, double* %4
%22 = fmul double %20, %21
%23 = call double @llvm.fmuladd.f64(double %18, double %19, double %22)
store double %23, double* %2
br label %24
24: ; preds = %11
%25 = load double, double* %2
%26 = fcmp oge double %25, 1.000000e+00
br i1 %26, label %11, label %27
27: ; preds = %24
%28 = load double, double* %2
%29 = call double @log(double %28)
%30 = fmul double -2.000000e+00, %29
%31 = load double, double* %2
%32 = fdiv double %30, %31
%33 = call double @sqrt(double %32)
store double %33, double* %5
%34 = load double, double* %4
%35 = load double, double* %5
%36 = fmul double %34, %35
store double %36, double* @random_unit_gaussian.dset
%37 = load double, double* %3
%38 = load double, double* %5
%39 = fmul double %37, %38
store double %39, double* %1
br label %40
40: ; preds = %27, %8
%41 = load double, double* %1
ret double %41
}

LLVM IR (-O2):
define double @random_unit_gaussian() {
br label %1
1: ; preds = %0, %1
%2 = tail call i32 (...) @random_unit_uniform()
%3 = sitofp i32 %2 to double
%4 = tail call double @llvm.fmuladd.f64(double %3, double 2.000000e+00, double -1.000000e+00)
%5 = tail call i32 (...) @random_unit_uniform()
%6 = sitofp i32 %5 to double
%7 = tail call double @llvm.fmuladd.f64(double %6, double 2.000000e+00, double -1.000000e+00)
%8 = fmul double %7, %7
%9 = tail call double @llvm.fmuladd.f64(double %4, double %4, double %8)
%10 = fcmp ult double %9, 1.000000e+00
br i1 %10, label %11, label %1
11: ; preds = %1
%12 = tail call double @log(double %9)
%13 = fmul double %12, -2.000000e+00
%14 = fdiv double %13, %9
%15 = tail call double @sqrt(double %14)
%16 = fmul double %4, %15
ret double %16
}