#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 RAND_MAX;
int log(double);
scalar_t__ rand();
double sqrt(int);
double ShareNormalRand(double mean, double dev) {
  static double V2, fac;
  static int phase = 0;
  double S, Z, U1, U2, V1;
  if (phase)
    Z = V2 * fac;
  else {
    do {
      U1 = (double)rand() / RAND_MAX;
      U2 = (double)rand() / RAND_MAX;
      V1 = 2 * U1 - 1;
      V2 = 2 * U2 - 1;
      S = V1 * V1 + V2 * V2;
    } while (S >= 1 || S == 0.0);
    fac = sqrt(-2 * log(S) / S);
    Z = V1 * fac;
  }
  phase = 1 - phase;
  Z = mean + dev * Z;
  return Z;
}


x86 assembly (clang, -O0):
<ShareNormalRand>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
cmpl   $0x0,0x2f07(%rip)
je     1169 <ShareNormalRand+0x39>
movsd  0x2ee9(%rip),%xmm0
mulsd  0x2ee9(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    127e <ShareNormalRand+0x14e>
jmp    116e <ShareNormalRand+0x3e>
mov    $0x0,%al
call   1050 <rand@plt>
cvtsi2sd %rax,%xmm0
mov    0x2e67(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    $0x0,%al
call   1050 <rand@plt>
cvtsi2sd %rax,%xmm0
mov    0x2e4b(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
addsd  %xmm0,%xmm0
movsd  0xe49(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x30(%rbp),%xmm0
addsd  %xmm0,%xmm0
movsd  0xe2f(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,0x2e63(%rip)
movsd  -0x38(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  0x2e51(%rip),%xmm1
mulsd  0x2e49(%rip),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
mov    $0x1,%al
movsd  0xdf5(%rip),%xmm1
ucomisd %xmm1,%xmm0
mov    %al,-0x39(%rbp)
jae    1237 <ShareNormalRand+0x107>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    116e <ShareNormalRand+0x3e>
movsd  -0x18(%rbp),%xmm0
call   1030 <log@plt>
imul   $0xfffffffe,%eax,%eax
cvtsi2sd %eax,%xmm0
divsd  -0x18(%rbp),%xmm0
cvttsd2si %xmm0,%edi
call   1040 <sqrt@plt>
movsd  %xmm0,0x2ddc(%rip)
movsd  -0x38(%rbp),%xmm0
mulsd  0x2dcf(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    $0x1,%eax
sub    0x2dc7(%rip),%eax
mov    %eax,0x2dc1(%rip)
movsd  -0x8(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ShareNormalRand>:
push   %rbx
sub    $0x20,%rsp
mov    0x2f15(%rip),%eax
test   %eax,%eax
je     1154 <ShareNormalRand+0x24>
movsd  0x2ef9(%rip),%xmm2
mulsd  0x2ef9(%rip),%xmm2
jmp    1233 <ShareNormalRand+0x103>
movsd  %xmm0,0x10(%rsp)
movsd  %xmm1,0x18(%rsp)
mov    0x2e81(%rip),%rbx
nopw   0x0(%rax,%rax,1)
xor    %eax,%eax
call   1050 <rand@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
divsd  (%rbx),%xmm0
movsd  %xmm0,(%rsp)
xor    %eax,%eax
call   1050 <rand@plt>
movsd  (%rsp),%xmm1
xorps  %xmm3,%xmm3
cvtsi2sd %rax,%xmm3
divsd  (%rbx),%xmm3
addsd  %xmm1,%xmm1
movsd  0xe54(%rip),%xmm2
addsd  %xmm2,%xmm1
addsd  %xmm3,%xmm3
addsd  %xmm2,%xmm3
movsd  %xmm3,0x2e80(%rip)
mulsd  %xmm3,%xmm3
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
addsd  %xmm3,%xmm0
ucomisd 0xe30(%rip),%xmm0
jae    1170 <ShareNormalRand+0x40>
ucomisd 0xe2e(%rip),%xmm0
jne    11e6 <ShareNormalRand+0xb6>
jnp    1170 <ShareNormalRand+0x40>
movsd  %xmm1,(%rsp)
movsd  %xmm0,0x8(%rsp)
call   1030 <log@plt>
add    %eax,%eax
neg    %eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
divsd  0x8(%rsp),%xmm0
cvttsd2si %xmm0,%edi
call   1040 <sqrt@plt>
movsd  (%rsp),%xmm2
movsd  %xmm0,0x2e2b(%rip)
mulsd  %xmm0,%xmm2
mov    0x2e29(%rip),%eax
movsd  0x18(%rsp),%xmm1
movsd  0x10(%rsp),%xmm0
mov    $0x1,%ecx
sub    %eax,%ecx
mov    %ecx,0x2e10(%rip)
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@ShareNormalRand.V2 = internal global double 0.000000e+00
@ShareNormalRand.fac = internal global double 0.000000e+00
@ShareNormalRand.phase = internal global i32 0
@RAND_MAX = global double 0.000000e+00
define double @ShareNormalRand(double %0, double %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
store double %0, double* %3
store double %1, double* %4
%10 = load i32, i32* @ShareNormalRand.phase
%11 = icmp ne i32 %10, 0
br i1 %11, label %12, label %16
12: ; preds = %2
%13 = load double, double* @ShareNormalRand.V2
%14 = load double, double* @ShareNormalRand.fac
%15 = fmul double %13, %14
store double %15, double* %6
br label %56
16: ; preds = %2
br label %17
17: ; preds = %42, %16
%18 = call i64 (...) @rand()
%19 = sitofp i64 %18 to double
%20 = load double, double* @RAND_MAX
%21 = fdiv double %19, %20
store double %21, double* %7
%22 = call i64 (...) @rand()
%23 = sitofp i64 %22 to double
%24 = load double, double* @RAND_MAX
%25 = fdiv double %23, %24
store double %25, double* %8
%26 = load double, double* %7
%27 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %26, double -1.000000e+00)
store double %27, double* %9
%28 = load double, double* %8
%29 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %28, double -1.000000e+00)
store double %29, double* @ShareNormalRand.V2
%30 = load double, double* %9
%31 = load double, double* %9
%32 = load double, double* @ShareNormalRand.V2
%33 = load double, double* @ShareNormalRand.V2
%34 = fmul double %32, %33
%35 = call double @llvm.fmuladd.f64(double %30, double %31, double %34)
store double %35, double* %5
br label %36
36: ; preds = %17
%37 = load double, double* %5
%38 = fcmp oge double %37, 1.000000e+00
br i1 %38, label %42, label %39
39: ; preds = %36
%40 = load double, double* %5
%41 = fcmp oeq double %40, 0.000000e+00
br label %42
42: ; preds = %39, %36
%43 = phi i1 [ true, %36 ], [ %41, %39 ]
br i1 %43, label %17, label %44
44: ; preds = %42
%45 = load double, double* %5
%46 = call i32 @log(double %45)
%47 = mul nsw i32 -2, %46
%48 = sitofp i32 %47 to double
%49 = load double, double* %5
%50 = fdiv double %48, %49
%51 = fptosi double %50 to i32
%52 = call double @sqrt(i32 %51)
store double %52, double* @ShareNormalRand.fac
%53 = load double, double* %9
%54 = load double, double* @ShareNormalRand.fac
%55 = fmul double %53, %54
store double %55, double* %6
br label %56
56: ; preds = %44, %12
%57 = load i32, i32* @ShareNormalRand.phase
%58 = sub nsw i32 1, %57
store i32 %58, i32* @ShareNormalRand.phase
%59 = load double, double* %3
%60 = load double, double* %4
%61 = load double, double* %6
%62 = call double @llvm.fmuladd.f64(double %60, double %61, double %59)
store double %62, double* %6
%63 = load double, double* %6
ret double %63
}

LLVM IR (-O2):
@ShareNormalRand.V2 = internal unnamed_addr global double 0.000000e+00
@ShareNormalRand.fac = internal unnamed_addr global double 0.000000e+00
@ShareNormalRand.phase = internal unnamed_addr global i32 0
@RAND_MAX = global double 0.000000e+00
define double @ShareNormalRand(double %0, double %1) {
%3 = load i32, i32* @ShareNormalRand.phase
%4 = icmp eq i32 %3, 0
br i1 %4, label %9, label %5
5: ; preds = %2
%6 = load double, double* @ShareNormalRand.V2
%7 = load double, double* @ShareNormalRand.fac
%8 = fmul double %6, %7
br label %34
9: ; preds = %2, %9
%10 = tail call i64 (...) @rand()
%11 = sitofp i64 %10 to double
%12 = load double, double* @RAND_MAX
%13 = fdiv double %11, %12
%14 = tail call i64 (...) @rand()
%15 = sitofp i64 %14 to double
%16 = load double, double* @RAND_MAX
%17 = fdiv double %15, %16
%18 = tail call double @llvm.fmuladd.f64(double %13, double 2.000000e+00, double -1.000000e+00)
%19 = tail call double @llvm.fmuladd.f64(double %17, double 2.000000e+00, double -1.000000e+00)
store double %19, double* @ShareNormalRand.V2
%20 = fmul double %19, %19
%21 = tail call double @llvm.fmuladd.f64(double %18, double %18, double %20)
%22 = fcmp oge double %21, 1.000000e+00
%23 = fcmp oeq double %21, 0.000000e+00
%24 = or i1 %22, %23
br i1 %24, label %9, label %25
25: ; preds = %9
%26 = tail call i32 @log(double %21)
%27 = mul nsw i32 %26, -2
%28 = sitofp i32 %27 to double
%29 = fdiv double %28, %21
%30 = fptosi double %29 to i32
%31 = tail call double @sqrt(i32 %30)
store double %31, double* @ShareNormalRand.fac
%32 = fmul double %18, %31
%33 = load i32, i32* @ShareNormalRand.phase
br label %34
34: ; preds = %25, %5
%35 = phi i32 [ %3, %5 ], [ %33, %25 ]
%36 = phi double [ %8, %5 ], [ %32, %25 ]
%37 = sub nsw i32 1, %35
store i32 %37, i32* @ShareNormalRand.phase
%38 = tail call double @llvm.fmuladd.f64(double %1, double %36, double %0)
ret double %38
}