#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 log(double);
int rand();
double sqrt(double);
float grandom(void) {
  double v1;
  double v2;
  double s;
  float x1;
  static float x2 = 0;
  static int toggle = 0;
  if (toggle) {
    toggle = 0;
    return x2;
  }
  do {
    v1 = -1.0 + 2.0 * ((rand() & 0x7fff) / ((float)0x7fff));
    v2 = -1.0 + 2.0 * ((rand() & 0x7fff) / ((float)0x7fff));
    s = v1 * v1 + v2 * v2;
  } while (s >= 1.0 || s == 0);
  s = sqrt(-2.0 * log(s) / s);
  x1 = v1 * s;
  x2 = v2 * s;
  toggle = 1;
  return x1;
}


x86 assembly (clang, -O0):
<grandom>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
cmpl   $0x0,0x2f01(%rip)
je     1161 <grandom+0x31>
movl   $0x0,0x2ef1(%rip)
movss  0x2ee5(%rip),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1294 <grandom+0x164>
jmp    1166 <grandom+0x36>
mov    $0x0,%al
call   1050 <rand@plt>
and    $0x7fff,%eax
cvtsi2ss %eax,%xmm0
movss  0xe9a(%rip),%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
movsd  0xe6e(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    $0x0,%al
call   1050 <rand@plt>
and    $0x7fff,%eax
cvtsi2ss %eax,%xmm0
movss  0xe65(%rip),%xmm1
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
movsd  0xe39(%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  0xe08(%rip),%xmm1
ucomisd %xmm1,%xmm0
mov    %al,-0x25(%rbp)
jae    1224 <grandom+0xf4>
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
mov    %al,-0x25(%rbp)
mov    -0x25(%rbp),%al
test   $0x1,%al
jne    1166 <grandom+0x36>
movsd  -0x20(%rbp),%xmm0
call   1030 <log@plt>
movaps %xmm0,%xmm1
movsd  0xdcc(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x20(%rbp),%xmm0
call   1040 <sqrt@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x2dbc(%rip)
movl   $0x1,0x2db6(%rip)
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<grandom>:
sub    $0x18,%rsp
cmpb   $0x0,0x2f05(%rip)
je     1160 <grandom+0x30>
movb   $0x0,0x2efc(%rip)
movss  0x2ef0(%rip),%xmm1
jmp    125d <grandom+0x12d>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
xor    %eax,%eax
call   1050 <rand@plt>
and    $0x7fff,%eax
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
movss  0xe85(%rip),%xmm1
divss  %xmm1,%xmm0
xorps  %xmm1,%xmm1
cvtss2sd %xmm0,%xmm1
addsd  %xmm1,%xmm1
movsd  0xe76(%rip),%xmm0
addsd  %xmm0,%xmm1
movsd  %xmm1,(%rsp)
xor    %eax,%eax
call   1050 <rand@plt>
and    $0x7fff,%eax
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
divss  0xe4a(%rip),%xmm0
xorps  %xmm1,%xmm1
cvtss2sd %xmm0,%xmm1
addsd  %xmm1,%xmm1
addsd  0xe3f(%rip),%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
movsd  (%rsp),%xmm0
mulsd  %xmm0,%xmm0
addsd  %xmm2,%xmm0
ucomisd 0xe2a(%rip),%xmm0
jae    1160 <grandom+0x30>
ucomisd 0xe2c(%rip),%xmm0
jne    11fc <grandom+0xcc>
jnp    1160 <grandom+0x30>
movsd  %xmm1,0x10(%rsp)
movsd  %xmm0,0x8(%rsp)
call   1030 <log@plt>
mulsd  0xe03(%rip),%xmm0
divsd  0x8(%rsp),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     122b <grandom+0xfb>
sqrtsd %xmm0,%xmm0
jmp    1230 <grandom+0x100>
call   1040 <sqrt@plt>
movsd  (%rsp),%xmm1
mulsd  %xmm0,%xmm1
cvtsd2ss %xmm1,%xmm1
movsd  0x10(%rsp),%xmm2
mulsd  %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsd2ss %xmm2,%xmm0
movss  %xmm0,0x2de6(%rip)
movb   $0x1,0x2de3(%rip)
movaps %xmm1,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
@grandom.x2 = internal global float 0.000000e+00
@grandom.toggle = internal global i32 0
define float @grandom() {
%1 = alloca float
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca float
%6 = load i32, i32* @grandom.toggle
%7 = icmp ne i32 %6, 0
br i1 %7, label %8, label %10
8: ; preds = %0
store i32 0, i32* @grandom.toggle
%9 = load float, float* @grandom.x2
store float %9, float* %1
br label %54
10: ; preds = %0
br label %11
11: ; preds = %36, %10
%12 = call i32 (...) @rand()
%13 = and i32 %12, 32767
%14 = sitofp i32 %13 to float
%15 = fdiv float %14, 3.276700e+04
%16 = fpext float %15 to double
%17 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %16, double -1.000000e+00)
store double %17, double* %2
%18 = call i32 (...) @rand()
%19 = and i32 %18, 32767
%20 = sitofp i32 %19 to float
%21 = fdiv float %20, 3.276700e+04
%22 = fpext float %21 to double
%23 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %22, double -1.000000e+00)
store double %23, double* %3
%24 = load double, double* %2
%25 = load double, double* %2
%26 = load double, double* %3
%27 = load double, double* %3
%28 = fmul double %26, %27
%29 = call double @llvm.fmuladd.f64(double %24, double %25, double %28)
store double %29, double* %4
br label %30
30: ; preds = %11
%31 = load double, double* %4
%32 = fcmp oge double %31, 1.000000e+00
br i1 %32, label %36, label %33
33: ; preds = %30
%34 = load double, double* %4
%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 %11, label %38
38: ; preds = %36
%39 = load double, double* %4
%40 = call double @log(double %39)
%41 = fmul double -2.000000e+00, %40
%42 = load double, double* %4
%43 = fdiv double %41, %42
%44 = call double @sqrt(double %43)
store double %44, double* %4
%45 = load double, double* %2
%46 = load double, double* %4
%47 = fmul double %45, %46
%48 = fptrunc double %47 to float
store float %48, float* %5
%49 = load double, double* %3
%50 = load double, double* %4
%51 = fmul double %49, %50
%52 = fptrunc double %51 to float
store float %52, float* @grandom.x2
store i32 1, i32* @grandom.toggle
%53 = load float, float* %5
store float %53, float* %1
br label %54
54: ; preds = %38, %8
%55 = load float, float* %1
ret float %55
}

LLVM IR (-O2):
@grandom.x2 = internal unnamed_addr global float 0.000000e+00
@grandom.toggle = internal unnamed_addr global i1 false
define float @grandom() {
%1 = load i1, i1* @grandom.toggle
br i1 %1, label %2, label %4
2: ; preds = %0
store i1 false, i1* @grandom.toggle
%3 = load float, float* @grandom.x2
br label %31
4: ; preds = %0, %4
%5 = tail call i32 (...) @rand()
%6 = and i32 %5, 32767
%7 = sitofp i32 %6 to float
%8 = fdiv float %7, 3.276700e+04
%9 = fpext float %8 to double
%10 = tail call double @llvm.fmuladd.f64(double %9, double 2.000000e+00, double -1.000000e+00)
%11 = tail call i32 (...) @rand()
%12 = and i32 %11, 32767
%13 = sitofp i32 %12 to float
%14 = fdiv float %13, 3.276700e+04
%15 = fpext float %14 to double
%16 = tail call double @llvm.fmuladd.f64(double %15, double 2.000000e+00, double -1.000000e+00)
%17 = fmul double %16, %16
%18 = tail call double @llvm.fmuladd.f64(double %10, double %10, double %17)
%19 = fcmp oge double %18, 1.000000e+00
%20 = fcmp oeq double %18, 0.000000e+00
%21 = or i1 %19, %20
br i1 %21, label %4, label %22
22: ; preds = %4
%23 = tail call double @log(double %18)
%24 = fmul double %23, -2.000000e+00
%25 = fdiv double %24, %18
%26 = tail call double @sqrt(double %25)
%27 = fmul double %10, %26
%28 = fptrunc double %27 to float
%29 = fmul double %16, %26
%30 = fptrunc double %29 to float
store float %30, float* @grandom.x2
store i1 true, i1* @grandom.toggle
br label %31
31: ; preds = %22, %2
%32 = phi float [ %3, %2 ], [ %28, %22 ]
ret float %32
}