#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 drand48();
double log(double);
double sqrt(double);
double pf_ran_gaussian(double sigma) {
  double x1, x2, w, r;
  do {
    do {
      r = drand48();
    } while (r == 0.0);
    x1 = 2.0 * r - 1.0;
    do {
      r = drand48();
    } while (r == 0.0);
    x2 = 2.0 * r - 1.0;
    w = x1 * x1 + x2 * x2;
  } while (w > 1.0 || w == 0.0);
  return (sigma * x2 * sqrt(-2.0 * log(w) / w));
}


x86 assembly (clang, -O0):
<pf_ran_gaussian>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x8(%rbp)
jmp    1142 <pf_ran_gaussian+0x12>
mov    $0x0,%al
call   1050 <drand48@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    116b <pf_ran_gaussian+0x3b>
jp     116b <pf_ran_gaussian+0x3b>
jmp    1142 <pf_ran_gaussian+0x12>
movsd  -0x28(%rbp),%xmm0
addsd  %xmm0,%xmm0
movsd  0xe84(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    $0x0,%al
call   1050 <drand48@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11ae <pf_ran_gaussian+0x7e>
jp     11ae <pf_ran_gaussian+0x7e>
jmp    1185 <pf_ran_gaussian+0x55>
movsd  -0x28(%rbp),%xmm0
addsd  %xmm0,%xmm0
movsd  0xe41(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm2
movsd  -0x18(%rbp),%xmm1
mulsd  -0x18(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mov    $0x1,%al
movsd  0xe10(%rip),%xmm1
ucomisd %xmm1,%xmm0
mov    %al,-0x29(%rbp)
ja     121c <pf_ran_gaussian+0xec>
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
mov    %al,-0x29(%rbp)
mov    -0x29(%rbp),%al
test   $0x1,%al
jne    113d <pf_ran_gaussian+0xd>
movsd  -0x8(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  0xdc5(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x20(%rbp),%xmm0
call   1040 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
mulsd  %xmm1,%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pf_ran_gaussian>:
sub    $0x18,%rsp
movsd  %xmm0,0x8(%rsp)
nopw   0x0(%rax,%rax,1)
xor    %eax,%eax
call   1050 <drand48@plt>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1153 <pf_ran_gaussian+0x23>
jnp    1140 <pf_ran_gaussian+0x10>
movsd  %xmm0,0x10(%rsp)
nopl   0x0(%rax)
xor    %eax,%eax
call   1050 <drand48@plt>
xorpd  %xmm3,%xmm3
ucomisd %xmm3,%xmm0
jne    1173 <pf_ran_gaussian+0x43>
jnp    1160 <pf_ran_gaussian+0x30>
movsd  0x10(%rsp),%xmm2
addsd  %xmm2,%xmm2
movsd  0xe7b(%rip),%xmm1
addsd  %xmm1,%xmm2
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
movapd %xmm0,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
ucomisd 0xe5f(%rip),%xmm2
ja     1140 <pf_ran_gaussian+0x10>
ucomisd %xmm3,%xmm2
jne    11b3 <pf_ran_gaussian+0x83>
jnp    1140 <pf_ran_gaussian+0x10>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movapd %xmm2,%xmm0
movsd  %xmm2,0x10(%rsp)
call   1030 <log@plt>
mulsd  0xe3a(%rip),%xmm0
divsd  0x10(%rsp),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     11ec <pf_ran_gaussian+0xbc>
sqrtsd %xmm0,%xmm0
jmp    11f1 <pf_ran_gaussian+0xc1>
call   1040 <sqrt@plt>
movsd  0x8(%rsp),%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define double @pf_ran_gaussian(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
store double %0, double* %2
br label %7
7: ; preds = %36, %1
br label %8
8: ; preds = %10, %7
%9 = call double (...) @drand48()
store double %9, double* %6
br label %10
10: ; preds = %8
%11 = load double, double* %6
%12 = fcmp oeq double %11, 0.000000e+00
br i1 %12, label %8, label %13
13: ; preds = %10
%14 = load double, double* %6
%15 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %14, double -1.000000e+00)
store double %15, double* %3
br label %16
16: ; preds = %18, %13
%17 = call double (...) @drand48()
store double %17, double* %6
br label %18
18: ; preds = %16
%19 = load double, double* %6
%20 = fcmp oeq double %19, 0.000000e+00
br i1 %20, label %16, label %21
21: ; preds = %18
%22 = load double, double* %6
%23 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %22, double -1.000000e+00)
store double %23, double* %4
%24 = load double, double* %3
%25 = load double, double* %3
%26 = load double, double* %4
%27 = load double, double* %4
%28 = fmul double %26, %27
%29 = call double @llvm.fmuladd.f64(double %24, double %25, double %28)
store double %29, double* %5
br label %30
30: ; preds = %21
%31 = load double, double* %5
%32 = fcmp ogt double %31, 1.000000e+00
br i1 %32, label %36, label %33
33: ; preds = %30
%34 = load double, double* %5
%35 = fcmp oeq double %34, 0.000000e+00
br label %36
36: ; preds = %33, %30
%37 = phi i1 [ true, %30 ], [ %35, %33 ]
br i1 %37, label %7, label %38
38: ; preds = %36
%39 = load double, double* %2
%40 = load double, double* %4
%41 = fmul double %39, %40
%42 = load double, double* %5
%43 = call double @log(double %42)
%44 = fmul double -2.000000e+00, %43
%45 = load double, double* %5
%46 = fdiv double %44, %45
%47 = call double @sqrt(double %46)
%48 = fmul double %41, %47
ret double %48
}

LLVM IR (-O2):
define double @pf_ran_gaussian(double %0) {
br label %2
2: ; preds = %5, %1
%3 = tail call double (...) @drand48()
%4 = fcmp oeq double %3, 0.000000e+00
br i1 %4, label %5, label %6
5: ; preds = %2, %9
br label %2
6: ; preds = %2, %6
%7 = tail call double (...) @drand48()
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %6, label %9
9: ; preds = %6
%10 = tail call double @llvm.fmuladd.f64(double %3, double 2.000000e+00, double -1.000000e+00)
%11 = tail call double @llvm.fmuladd.f64(double %7, double 2.000000e+00, double -1.000000e+00)
%12 = fmul double %11, %11
%13 = tail call double @llvm.fmuladd.f64(double %10, double %10, double %12)
%14 = fcmp ogt double %13, 1.000000e+00
%15 = fcmp oeq double %13, 0.000000e+00
%16 = or i1 %14, %15
br i1 %16, label %5, label %17
17: ; preds = %9
%18 = fmul double %11, %0
%19 = tail call double @log(double %13)
%20 = fmul double %19, -2.000000e+00
%21 = fdiv double %20, %13
%22 = tail call double @sqrt(double %21)
%23 = fmul double %18, %22
ret double %23
}