#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 */
scalar_t__ RAND_MAX;
float cos(double);
int log(double);
double rand();
float sin(double);
float sqrt(double);
float rand_normal() {
  static int haveSpare = 0;
  static double rand1, rand2;
  if (haveSpare) {
    haveSpare = 0;
    return sqrt(rand1) * sin(rand2);
  }
  haveSpare = 1;
  rand1 = rand() / ((double)RAND_MAX);
  if (rand1 < 1e-100)
    rand1 = 1e-100;
  rand1 = -2 * log(rand1);
  rand2 = (rand() / ((double)RAND_MAX)) * 6.2831853071795864769252866f;
  return sqrt(rand1) * cos(rand2);
}


x86 assembly (clang, -O0):
<rand_normal>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
cmpl   $0x0,0x2ef1(%rip)
je     11a4 <rand_normal+0x54>
movl   $0x0,0x2ee1(%rip)
movsd  0x2ee1(%rip),%xmm0
call   1060 <sqrt@plt>
movss  %xmm0,-0x8(%rbp)
movsd  0x2ed7(%rip),%xmm0
call   1030 <sin@plt>
movaps %xmm0,%xmm1
movss  -0x8(%rbp),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    126d <rand_normal+0x11d>
movl   $0x1,0x2ea2(%rip)
mov    $0x0,%al
call   1070 <rand@plt>
mov    0x2e2c(%rip),%rax
cvtsi2sdq (%rax),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,0x2e8b(%rip)
movsd  0xe2b(%rip),%xmm0
ucomisd 0x2e7b(%rip),%xmm0
jbe    11f3 <rand_normal+0xa3>
movsd  0xe15(%rip),%xmm0
movsd  %xmm0,0x2e65(%rip)
movsd  0x2e5d(%rip),%xmm0
call   1050 <log@plt>
imul   $0xfffffffe,%eax,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,0x2e46(%rip)
mov    $0x0,%al
call   1070 <rand@plt>
mov    0x2dc8(%rip),%rax
cvtsi2sdq (%rax),%xmm1
divsd  %xmm1,%xmm0
movsd  0xdd7(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x2e23(%rip)
movsd  0x2e13(%rip),%xmm0
call   1060 <sqrt@plt>
movss  %xmm0,-0xc(%rbp)
movsd  0x2e09(%rip),%xmm0
call   1040 <cos@plt>
movaps %xmm0,%xmm1
movss  -0xc(%rbp),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rand_normal>:
push   %rbx
sub    $0x10,%rsp
cmpb   $0x1,0x2ef4(%rip)
jne    118a <rand_normal+0x3a>
movb   $0x0,0x2eeb(%rip)
movsd  0x2eeb(%rip),%xmm0
call   1060 <sqrt@plt>
movss  %xmm0,0xc(%rsp)
movsd  0x2ee0(%rip),%xmm0
call   1030 <sin@plt>
jmp    121b <rand_normal+0xcb>
movb   $0x1,0x2ebf(%rip)
xor    %eax,%eax
call   1070 <rand@plt>
mov    0x2e49(%rip),%rbx
cvtsi2sdq (%rbx),%xmm1
divsd  %xmm1,%xmm0
movsd  0xe50(%rip),%xmm1
maxsd  %xmm0,%xmm1
movsd  %xmm1,0x2e9c(%rip)
movapd %xmm1,%xmm0
call   1050 <log@plt>
add    %eax,%eax
neg    %eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  %xmm0,0x2e80(%rip)
xor    %eax,%eax
call   1070 <rand@plt>
xorps  %xmm1,%xmm1
cvtsi2sdq (%rbx),%xmm1
divsd  %xmm1,%xmm0
mulsd  0xe15(%rip),%xmm0
movsd  %xmm0,0x2e65(%rip)
movsd  0x2e55(%rip),%xmm0
call   1060 <sqrt@plt>
movss  %xmm0,0xc(%rsp)
movsd  0x2e4a(%rip),%xmm0
call   1040 <cos@plt>
mulss  0xc(%rsp),%xmm0
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@rand_normal.haveSpare = internal global i32 0
@rand_normal.rand1 = internal global double 0.000000e+00
@rand_normal.rand2 = internal global double 0.000000e+00
@RAND_MAX = global i64 0
define float @rand_normal() {
%1 = alloca float
%2 = load i32, i32* @rand_normal.haveSpare
%3 = icmp ne i32 %2, 0
br i1 %3, label %4, label %10
4: ; preds = %0
store i32 0, i32* @rand_normal.haveSpare
%5 = load double, double* @rand_normal.rand1
%6 = call float @sqrt(double %5)
%7 = load double, double* @rand_normal.rand2
%8 = call float @sin(double %7)
%9 = fmul float %6, %8
store float %9, float* %1
br label %33
10: ; preds = %0
store i32 1, i32* @rand_normal.haveSpare
%11 = call double (...) @rand()
%12 = load i64, i64* @RAND_MAX
%13 = sitofp i64 %12 to double
%14 = fdiv double %11, %13
store double %14, double* @rand_normal.rand1
%15 = load double, double* @rand_normal.rand1
%16 = fcmp olt double %15, 1.000000e-100
br i1 %16, label %17, label %18
17: ; preds = %10
store double 1.000000e-100, double* @rand_normal.rand1
br label %18
18: ; preds = %17, %10
%19 = load double, double* @rand_normal.rand1
%20 = call i32 @log(double %19)
%21 = mul nsw i32 -2, %20
%22 = sitofp i32 %21 to double
store double %22, double* @rand_normal.rand1
%23 = call double (...) @rand()
%24 = load i64, i64* @RAND_MAX
%25 = sitofp i64 %24 to double
%26 = fdiv double %23, %25
%27 = fmul double %26, 0x401921FB60000000
store double %27, double* @rand_normal.rand2
%28 = load double, double* @rand_normal.rand1
%29 = call float @sqrt(double %28)
%30 = load double, double* @rand_normal.rand2
%31 = call float @cos(double %30)
%32 = fmul float %29, %31
store float %32, float* %1
br label %33
33: ; preds = %18, %4
%34 = load float, float* %1
ret float %34
}

LLVM IR (-O2):
@rand_normal.haveSpare = internal unnamed_addr global i1 false
@rand_normal.rand1 = internal unnamed_addr global double 0.000000e+00
@rand_normal.rand2 = internal unnamed_addr global double 0.000000e+00
@RAND_MAX = global i64 0
define float @rand_normal() {
%1 = load i1, i1* @rand_normal.haveSpare
br i1 %1, label %2, label %8
2: ; preds = %0
store i1 false, i1* @rand_normal.haveSpare
%3 = load double, double* @rand_normal.rand1
%4 = tail call float @sqrt(double %3)
%5 = load double, double* @rand_normal.rand2
%6 = tail call float @sin(double %5)
%7 = fmul float %4, %6
br label %28
8: ; preds = %0
store i1 true, i1* @rand_normal.haveSpare
%9 = tail call double (...) @rand()
%10 = load i64, i64* @RAND_MAX
%11 = sitofp i64 %10 to double
%12 = fdiv double %9, %11
%13 = fcmp olt double %12, 1.000000e-100
%14 = select i1 %13, double 1.000000e-100, double %12
store double %14, double* @rand_normal.rand1
%15 = tail call i32 @log(double %14)
%16 = mul nsw i32 %15, -2
%17 = sitofp i32 %16 to double
store double %17, double* @rand_normal.rand1
%18 = tail call double (...) @rand()
%19 = load i64, i64* @RAND_MAX
%20 = sitofp i64 %19 to double
%21 = fdiv double %18, %20
%22 = fmul double %21, 0x401921FB60000000
store double %22, double* @rand_normal.rand2
%23 = load double, double* @rand_normal.rand1
%24 = tail call float @sqrt(double %23)
%25 = load double, double* @rand_normal.rand2
%26 = tail call float @cos(double %25)
%27 = fmul float %24, %26
br label %28
28: ; preds = %8, %2
%29 = phi float [ %7, %2 ], [ %27, %8 ]
ret float %29
}