#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 exp(double);
double floor(double);
double log(double);
double ran1();
double sqrt(double);
double tan(double);
void _poidev(float *xmv, long n) {
  double gammln(double xx);
  static double sq, alxm, g, oldm = (-1.0);
  double xm, em, t, y, y1;
  long i;
  for (i = 0; i < n; i++) {
    xm = (double)xmv[i];
    if (xm == 0.0f)
      continue;
    if (xm < 20.0) {
      if (xm != oldm) {
        oldm = xm;
        g = exp(-xm);
      }
      em = -1;
      t = 1.0;
      do {
        ++em;
        t *= ran1();
      } while (t > g);
    } else {
      if (xm != oldm) {
        oldm = xm;
        sq = sqrt(2.0 * xm);
        alxm = log(xm);
        g = xm * alxm - gammln(xm + 1.0);
      }
      do {
        do {
          y = tan(3.1415926535897932384626433832 * ran1());
          em = sq * y + xm;
        } while (em < 0.0);
        em = floor(em);
        t = 0.9 * (1.0 + y * y) * exp(em * alxm - gammln(em + 1.0) - g);
      } while (ran1() > t);
    }
    xmv[i] = (float)em;
  }
}


x86 assembly (clang, -O0):
<_poidev>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x10(%rbp),%rax
jge    147b <_poidev+0x30b>
mov    -0x8(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11c9 <_poidev+0x59>
jp     11c9 <_poidev+0x59>
jmp    146a <_poidev+0x2fa>
movsd  0xe2f(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    1285 <_poidev+0x115>
movsd  -0x18(%rbp),%xmm0
ucomisd 0x2e6f(%rip),%xmm0
jne    11fa <_poidev+0x8a>
jp     11fa <_poidev+0x8a>
jmp    1230 <_poidev+0xc0>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,0x2e51(%rip)
movsd  -0x18(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,0x2e48(%rip)
movsd  0xdf0(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xdc3(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xdb6(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    $0x0,%al
call   1050 <ran1@plt>
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
ucomisd 0x2dfe(%rip),%xmm0
ja     124a <_poidev+0xda>
jmp    1454 <_poidev+0x2e4>
movsd  -0x18(%rbp),%xmm0
ucomisd 0x2dc6(%rip),%xmm0
jne    12a3 <_poidev+0x133>
jp     12a3 <_poidev+0x133>
jmp    1339 <_poidev+0x1c9>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,0x2da8(%rip)
movsd  0xd58(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
call   1070 <sqrt@plt>
movsd  %xmm0,0x2d9e(%rip)
movsd  -0x18(%rbp),%xmm0
call   1060 <log@plt>
movsd  %xmm0,0x2d94(%rip)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0x2d82(%rip),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0xd0d(%rip),%xmm0
addsd  -0x18(%rbp),%xmm0
call   1080 <gammln@plt>
movsd  -0x50(%rbp),%xmm2
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x2d3f(%rip)
jmp    133e <_poidev+0x1ce>
jmp    1343 <_poidev+0x1d3>
mov    $0x0,%al
call   1050 <ran1@plt>
movaps %xmm0,%xmm1
movsd  0xcc3(%rip),%xmm0
mulsd  %xmm1,%xmm0
call   1040 <tan@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  0x2cfd(%rip),%xmm0
movsd  -0x30(%rbp),%xmm2
movsd  -0x18(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x20(%rbp),%xmm0
ja     1343 <_poidev+0x1d3>
movsd  -0x20(%rbp),%xmm0
call   1090 <floor@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x30(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm0,%xmm1
movsd  0xc53(%rip),%xmm0
addsd  %xmm0,%xmm1
movsd  0xc5f(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  0x2c94(%rip),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  0xc1f(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
call   1080 <gammln@plt>
movsd  -0x68(%rbp),%xmm2
movaps %xmm0,%xmm1
movsd  -0x60(%rbp),%xmm0
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
subsd  0x2c51(%rip),%xmm0
call   1030 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    $0x0,%al
call   1050 <ran1@plt>
ucomisd -0x28(%rbp),%xmm0
ja     133e <_poidev+0x1ce>
jmp    1454 <_poidev+0x2e4>
movsd  -0x20(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1188 <_poidev+0x18>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_poidev>:
push   %r15
push   %r14
push   %rbx
sub    $0x30,%rsp
test   %rsi,%rsi
jle    13bf <_poidev+0x24f>
mov    %rsi,%r14
mov    %rdi,%r15
xorps  %xmm1,%xmm1
movsd  0xe75(%rip),%xmm2
xor    %ebx,%ebx
jmp    11bb <_poidev+0x4b>
nopw   0x0(%rax,%rax,1)
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%r15,%rbx,4)
xorpd  %xmm1,%xmm1
add    $0x1,%rbx
cmp    %r14,%rbx
je     13bf <_poidev+0x24f>
movss  (%r15,%rbx,4),%xmm0
ucomiss %xmm1,%xmm0
jne    11c8 <_poidev+0x58>
jnp    11ae <_poidev+0x3e>
xorps  %xmm3,%xmm3
cvtss2sd %xmm0,%xmm3
movss  0xe29(%rip),%xmm1
ucomiss %xmm0,%xmm1
movsd  0x2e76(%rip),%xmm0
jbe    126c <_poidev+0xfc>
ucomisd %xmm3,%xmm0
jne    11f0 <_poidev+0x80>
jnp    1219 <_poidev+0xa9>
movsd  %xmm3,0x2e60(%rip)
xorpd  0xe30(%rip),%xmm3
movapd %xmm3,%xmm0
call   1030 <exp@plt>
movsd  0xdf7(%rip),%xmm2
movsd  %xmm0,0x2e5f(%rip)
movapd %xmm2,%xmm1
movsd  0xdfb(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nop
movsd  %xmm1,(%rsp)
addsd  %xmm2,%xmm0
movsd  %xmm0,0x8(%rsp)
xor    %eax,%eax
call   1050 <ran1@plt>
movsd  (%rsp),%xmm1
movsd  0xdb5(%rip),%xmm2
mulsd  %xmm0,%xmm1
movsd  0x8(%rsp),%xmm0
ucomisd 0x2e13(%rip),%xmm1
ja     1230 <_poidev+0xc0>
jmp    11a0 <_poidev+0x30>
ucomisd %xmm3,%xmm0
movaps %xmm3,0x10(%rsp)
jne    1279 <_poidev+0x109>
jnp    12f0 <_poidev+0x180>
movsd  %xmm3,0x2dd7(%rip)
movapd %xmm3,%xmm0
addsd  %xmm3,%xmm0
ucomisd 0xd97(%rip),%xmm0
jb     1299 <_poidev+0x129>
sqrtsd %xmm0,%xmm0
jmp    12a3 <_poidev+0x133>
call   1070 <sqrt@plt>
movaps 0x10(%rsp),%xmm3
movsd  %xmm0,0x2dbd(%rip)
movaps %xmm3,%xmm0
call   1060 <log@plt>
movsd  %xmm0,(%rsp)
movsd  %xmm0,0x2db0(%rip)
movapd 0x10(%rsp),%xmm0
addsd  0xd3a(%rip),%xmm0
call   1080 <gammln@plt>
movsd  (%rsp),%xmm1
mulsd  0x10(%rsp),%xmm1
subsd  %xmm0,%xmm1
movsd  %xmm1,0x2d8e(%rip)
nopw   0x0(%rax,%rax,1)
xor    %eax,%eax
call   1050 <ran1@plt>
mulsd  0xd11(%rip),%xmm0
call   1040 <tan@plt>
movapd %xmm0,%xmm2
movsd  0x2d58(%rip),%xmm0
mulsd  %xmm2,%xmm0
addsd  0x10(%rsp),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
ja     12f0 <_poidev+0x180>
movsd  %xmm2,(%rsp)
call   1090 <floor@plt>
movapd %xmm0,%xmm2
movsd  (%rsp),%xmm3
mulsd  %xmm3,%xmm3
movsd  0xcc5(%rip),%xmm1
addsd  %xmm1,%xmm3
mulsd  0xcc9(%rip),%xmm3
movsd  %xmm3,(%rsp)
addsd  %xmm1,%xmm0
movsd  0x2d10(%rip),%xmm1
movsd  %xmm2,0x8(%rsp)
mulsd  %xmm2,%xmm1
movsd  %xmm1,0x28(%rsp)
call   1080 <gammln@plt>
movsd  0x28(%rsp),%xmm1
subsd  %xmm0,%xmm1
subsd  0x2cf1(%rip),%xmm1
movapd %xmm1,%xmm0
call   1030 <exp@plt>
mulsd  (%rsp),%xmm0
movsd  %xmm0,(%rsp)
xor    %eax,%eax
call   1050 <ran1@plt>
ucomisd (%rsp),%xmm0
ja     12f0 <_poidev+0x180>
movsd  0xc54(%rip),%xmm2
movsd  0x8(%rsp),%xmm0
jmp    11a0 <_poidev+0x30>
add    $0x30,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@_poidev.sq = internal global double 0.000000e+00
@_poidev.alxm = internal global double 0.000000e+00
@_poidev.g = internal global double 0.000000e+00
@_poidev.oldm = internal global double -1.000000e+00
define void @_poidev(float* %0, i64 %1) {
%3 = alloca float*
%4 = alloca i64
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca i64
store float* %0, float** %3
store i64 %1, i64* %4
store i64 0, i64* %10
br label %11
11: ; preds = %108, %2
%12 = load i64, i64* %10
%13 = load i64, i64* %4
%14 = icmp slt i64 %12, %13
br i1 %14, label %15, label %111
15: ; preds = %11
%16 = load float*, float** %3
%17 = load i64, i64* %10
%18 = getelementptr inbounds float, float* %16, i64 %17
%19 = load float, float* %18
%20 = fpext float %19 to double
store double %20, double* %5
%21 = load double, double* %5
%22 = fcmp oeq double %21, 0.000000e+00
br i1 %22, label %23, label %24
23: ; preds = %15
br label %108
24: ; preds = %15
%25 = load double, double* %5
%26 = fcmp olt double %25, 2.000000e+01
br i1 %26, label %27, label %48
27: ; preds = %24
%28 = load double, double* %5
%29 = load double, double* @_poidev.oldm
%30 = fcmp une double %28, %29
br i1 %30, label %31, label %36
31: ; preds = %27
%32 = load double, double* %5
store double %32, double* @_poidev.oldm
%33 = load double, double* %5
%34 = fneg double %33
%35 = call double @exp(double %34)
store double %35, double* @_poidev.g
br label %36
36: ; preds = %31, %27
store double -1.000000e+00, double* %6
store double 1.000000e+00, double* %7
br label %37
37: ; preds = %43, %36
%38 = load double, double* %6
%39 = fadd double %38, 1.000000e+00
store double %39, double* %6
%40 = call double (...) @ran1()
%41 = load double, double* %7
%42 = fmul double %41, %40
store double %42, double* %7
br label %43
43: ; preds = %37
%44 = load double, double* %7
%45 = load double, double* @_poidev.g
%46 = fcmp ogt double %44, %45
br i1 %46, label %37, label %47
47: ; preds = %43
br label %102
48: ; preds = %24
%49 = load double, double* %5
%50 = load double, double* @_poidev.oldm
%51 = fcmp une double %49, %50
br i1 %51, label %52, label %66
52: ; preds = %48
%53 = load double, double* %5
store double %53, double* @_poidev.oldm
%54 = load double, double* %5
%55 = fmul double 2.000000e+00, %54
%56 = call double @sqrt(double %55)
store double %56, double* @_poidev.sq
%57 = load double, double* %5
%58 = call double @log(double %57)
store double %58, double* @_poidev.alxm
%59 = load double, double* %5
%60 = load double, double* @_poidev.alxm
%61 = load double, double* %5
%62 = fadd double %61, 1.000000e+00
%63 = call double @gammln(double %62)
%64 = fneg double %63
%65 = call double @llvm.fmuladd.f64(double %59, double %60, double %64)
store double %65, double* @_poidev.g
br label %66
66: ; preds = %52, %48
br label %67
67: ; preds = %97, %66
br label %68
68: ; preds = %76, %67
%69 = call double (...) @ran1()
%70 = fmul double 0x400921FB54442D18, %69
%71 = call double @tan(double %70)
store double %71, double* %8
%72 = load double, double* @_poidev.sq
%73 = load double, double* %8
%74 = load double, double* %5
%75 = call double @llvm.fmuladd.f64(double %72, double %73, double %74)
store double %75, double* %6
br label %76
76: ; preds = %68
%77 = load double, double* %6
%78 = fcmp olt double %77, 0.000000e+00
br i1 %78, label %68, label %79
79: ; preds = %76
%80 = load double, double* %6
%81 = call double @llvm.floor.f64(double %80)
store double %81, double* %6
%82 = load double, double* %8
%83 = load double, double* %8
%84 = call double @llvm.fmuladd.f64(double %82, double %83, double 1.000000e+00)
%85 = fmul double 9.000000e-01, %84
%86 = load double, double* %6
%87 = load double, double* @_poidev.alxm
%88 = load double, double* %6
%89 = fadd double %88, 1.000000e+00
%90 = call double @gammln(double %89)
%91 = fneg double %90
%92 = call double @llvm.fmuladd.f64(double %86, double %87, double %91)
%93 = load double, double* @_poidev.g
%94 = fsub double %92, %93
%95 = call double @exp(double %94)
%96 = fmul double %85, %95
store double %96, double* %7
br label %97
97: ; preds = %79
%98 = call double (...) @ran1()
%99 = load double, double* %7
%100 = fcmp ogt double %98, %99
br i1 %100, label %67, label %101
101: ; preds = %97
br label %102
102: ; preds = %101, %47
%103 = load double, double* %6
%104 = fptrunc double %103 to float
%105 = load float*, float** %3
%106 = load i64, i64* %10
%107 = getelementptr inbounds float, float* %105, i64 %106
store float %104, float* %107
br label %108
108: ; preds = %102, %23
%109 = load i64, i64* %10
%110 = add nsw i64 %109, 1
store i64 %110, i64* %10
br label %11
111: ; preds = %11
ret void
}

LLVM IR (-O2):
@_poidev.sq = internal unnamed_addr global double 0.000000e+00
@_poidev.alxm = internal unnamed_addr global double 0.000000e+00
@_poidev.g = internal unnamed_addr global double 0.000000e+00
@_poidev.oldm = internal unnamed_addr global double -1.000000e+00
define void @_poidev(float* nocapture %0, i64 %1) {
%3 = icmp sgt i64 %1, 0
br i1 %3, label %4, label %66
4: ; preds = %2, %63
%5 = phi i64 [ %64, %63 ], [ 0, %2 ]
%6 = getelementptr inbounds float, float* %0, i64 %5
%7 = load float, float* %6
%8 = fpext float %7 to double
%9 = fcmp oeq float %7, 0.000000e+00
br i1 %9, label %63, label %10
10: ; preds = %4
%11 = fcmp olt float %7, 2.000000e+01
%12 = load double, double* @_poidev.oldm
%13 = fcmp une double %12, %8
br i1 %11, label %14, label %27
14: ; preds = %10
br i1 %13, label %15, label %18
15: ; preds = %14
store double %8, double* @_poidev.oldm
%16 = fneg double %8
%17 = tail call double @exp(double %16)
store double %17, double* @_poidev.g
br label %18
18: ; preds = %15, %14
br label %19
19: ; preds = %18, %19
%20 = phi double [ %24, %19 ], [ 1.000000e+00, %18 ]
%21 = phi double [ %22, %19 ], [ -1.000000e+00, %18 ]
%22 = fadd double %21, 1.000000e+00
%23 = tail call double (...) @ran1()
%24 = fmul double %20, %23
%25 = load double, double* @_poidev.g
%26 = fcmp ogt double %24, %25
br i1 %26, label %19, label %60
27: ; preds = %10
br i1 %13, label %28, label %36
28: ; preds = %27
store double %8, double* @_poidev.oldm
%29 = fmul double %8, 2.000000e+00
%30 = tail call double @sqrt(double %29)
store double %30, double* @_poidev.sq
%31 = tail call double @log(double %8)
store double %31, double* @_poidev.alxm
%32 = fadd double %8, 1.000000e+00
%33 = tail call double @gammln(double %32)
%34 = fneg double %33
%35 = tail call double @llvm.fmuladd.f64(double %8, double %31, double %34)
store double %35, double* @_poidev.g
br label %36
36: ; preds = %27, %28
br label %37
37: ; preds = %44, %36
%38 = tail call double (...) @ran1()
%39 = fmul double %38, 0x400921FB54442D18
%40 = tail call double @tan(double %39)
%41 = load double, double* @_poidev.sq
%42 = tail call double @llvm.fmuladd.f64(double %41, double %40, double %8)
%43 = fcmp olt double %42, 0.000000e+00
br i1 %43, label %44, label %45
44: ; preds = %37, %45
br label %37
45: ; preds = %37
%46 = tail call double @llvm.floor.f64(double %42)
%47 = tail call double @llvm.fmuladd.f64(double %40, double %40, double 1.000000e+00)
%48 = fmul double %47, 9.000000e-01
%49 = load double, double* @_poidev.alxm
%50 = fadd double %46, 1.000000e+00
%51 = tail call double @gammln(double %50)
%52 = fneg double %51
%53 = tail call double @llvm.fmuladd.f64(double %46, double %49, double %52)
%54 = load double, double* @_poidev.g
%55 = fsub double %53, %54
%56 = tail call double @exp(double %55)
%57 = fmul double %48, %56
%58 = tail call double (...) @ran1()
%59 = fcmp ogt double %58, %57
br i1 %59, label %44, label %60
60: ; preds = %45, %19
%61 = phi double [ %22, %19 ], [ %46, %45 ]
%62 = fptrunc double %61 to float
store float %62, float* %6
br label %63
63: ; preds = %4, %60
%64 = add nuw nsw i64 %5, 1
%65 = icmp eq i64 %64, %1
br i1 %65, label %66, label %4
66: ; preds = %63, %2
ret void
}