void rand3(x, y, z) float *x, *y, *z;
{
  float randf();
  float alpha, norm, x1, x2;
  norm = 2.;
  while (norm > 1.) {
    x1 = 2. * randf() - 1;
    x2 = 2. * randf() - 1;
    norm = x1 * x1 + x2 * x2;
  }
  *x = x1;
  *y = x2;
  norm = sqrt(1. - norm);
  *z = norm;
  if (randf() < 0.5)
    *z = -norm;
}


x86 assembly (clang, -O0):
<rand3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movss  0xec4(%rip),%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xeb6(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11ca <rand3+0xaa>
mov    $0x0,%al
call   1030 <randf@plt>
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
movsd  0xea5(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    $0x0,%al
call   1030 <randf@plt>
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
movsd  0xe81(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x24(%rbp),%xmm0
movss  -0x24(%rbp),%xmm2
movss  -0x28(%rbp),%xmm1
mulss  -0x28(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
jmp    1141 <rand3+0x21>
movss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x20(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xe13(%rip),%xmm0
subsd  %xmm1,%xmm0
call   1040 <sqrt@plt>
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
mov    $0x0,%al
call   1030 <randf@plt>
cvtss2sd %xmm0,%xmm1
movsd  0xde9(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    124b <rand3+0x12b>
movss  -0x20(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rand3>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
xor    %eax,%eax
call   1030 <randf@plt>
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
movsd  0xea9(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rsp)
xor    %eax,%eax
call   1030 <randf@plt>
movss  (%rsp),%xmm3
cvtss2sd %xmm0,%xmm0
addsd  %xmm0,%xmm0
addsd  0xe80(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
movaps %xmm0,%xmm2
mulss  %xmm0,%xmm2
movaps %xmm3,%xmm1
mulss  %xmm3,%xmm1
addss  %xmm2,%xmm1
ucomiss 0xe73(%rip),%xmm1
ja     1140 <rand3+0x20>
cvtss2sd %xmm1,%xmm1
movss  %xmm3,(%rbx)
movss  %xmm0,(%r15)
movsd  0xe54(%rip),%xmm0
subsd  %xmm1,%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     11c8 <rand3+0xa8>
sqrtsd %xmm0,%xmm0
jmp    11cd <rand3+0xad>
call   1040 <sqrt@plt>
cvtsd2ss %xmm0,%xmm0
movaps %xmm0,(%rsp)
movss  %xmm0,(%r14)
xor    %eax,%eax
call   1030 <randf@plt>
movss  0xe2b(%rip),%xmm1
ucomiss %xmm0,%xmm1
jbe    11fe <rand3+0xde>
movaps (%rsp),%xmm0
xorps  0xe27(%rip),%xmm0
movss  %xmm0,(%r14)
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @rand3(float* %0, float* %1, float* %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca float*
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
store float* %0, float** %4
store float* %1, float** %5
store float* %2, float** %6
store float 2.000000e+00, float* %8
br label %11
11: ; preds = %15, %3
%12 = load float, float* %8
%13 = fpext float %12 to double
%14 = fcmp ogt double %13, 1.000000e+00
br i1 %14, label %15, label %30
15: ; preds = %11
%16 = call float (...) @randf()
%17 = fpext float %16 to double
%18 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %17, double -1.000000e+00)
%19 = fptrunc double %18 to float
store float %19, float* %9
%20 = call float (...) @randf()
%21 = fpext float %20 to double
%22 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %21, double -1.000000e+00)
%23 = fptrunc double %22 to float
store float %23, float* %10
%24 = load float, float* %9
%25 = load float, float* %9
%26 = load float, float* %10
%27 = load float, float* %10
%28 = fmul float %26, %27
%29 = call float @llvm.fmuladd.f32(float %24, float %25, float %28)
store float %29, float* %8
br label %11
30: ; preds = %11
%31 = load float, float* %9
%32 = load float*, float** %4
store float %31, float* %32
%33 = load float, float* %10
%34 = load float*, float** %5
store float %33, float* %34
%35 = load float, float* %8
%36 = fpext float %35 to double
%37 = fsub double 1.000000e+00, %36
%38 = call double @sqrt(double %37)
%39 = fptrunc double %38 to float
store float %39, float* %8
%40 = load float, float* %8
%41 = load float*, float** %6
store float %40, float* %41
%42 = call float (...) @randf()
%43 = fpext float %42 to double
%44 = fcmp olt double %43, 5.000000e-01
br i1 %44, label %45, label %49
45: ; preds = %30
%46 = load float, float* %8
%47 = fneg float %46
%48 = load float*, float** %6
store float %47, float* %48
br label %49
49: ; preds = %45, %30
ret void
}

LLVM IR (-O2):
define void @rand3(float* nocapture writeonly %0, float* nocapture writeonly %1, float* nocapture writeonly %2) {
br label %4
4: ; preds = %3, %4
%5 = tail call float (...) @randf()
%6 = fpext float %5 to double
%7 = tail call double @llvm.fmuladd.f64(double %6, double 2.000000e+00, double -1.000000e+00)
%8 = fptrunc double %7 to float
%9 = tail call float (...) @randf()
%10 = fpext float %9 to double
%11 = tail call double @llvm.fmuladd.f64(double %10, double 2.000000e+00, double -1.000000e+00)
%12 = fptrunc double %11 to float
%13 = fmul float %12, %12
%14 = tail call float @llvm.fmuladd.f32(float %8, float %8, float %13)
%15 = fcmp ogt float %14, 1.000000e+00
br i1 %15, label %4, label %16
16: ; preds = %4
%17 = fpext float %14 to double
store float %8, float* %0
store float %12, float* %1
%18 = fsub double 1.000000e+00, %17
%19 = tail call double @sqrt(double %18)
%20 = fptrunc double %19 to float
store float %20, float* %2
%21 = tail call float (...) @randf()
%22 = fcmp olt float %21, 5.000000e-01
br i1 %22, label %23, label %25
23: ; preds = %16
%24 = fneg float %20
store float %24, float* %2
br label %25
25: ; preds = %23, %16
ret void
}