float ran4(long *idum) {
  void psdes(unsigned long *lword, unsigned long *irword);
  unsigned long irword, itemp, lword;
  static long idums = 0;
  static unsigned long jflone = 0x3f800000;
  static unsigned long jflmsk = 0x007fffff;
  if (*idum < 0) {
    idums = -(*idum);
    *idum = 1;
  }
  irword = (*idum);
  lword = idums;
  psdes(&lword, &irword);
  itemp = jflone | (jflmsk & irword);
  ++(*idum);
  return (*(float *)&itemp) - 1.0;
}


x86 assembly (clang, -O0):
<ran4>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
cmpq   $0x0,(%rax)
jge    1145 <ran4+0x35>
mov    -0x8(%rbp),%rcx
xor    %eax,%eax
sub    (%rcx),%rax
mov    %rax,0x2f06(%rip)
mov    -0x8(%rbp),%rax
movq   $0x1,(%rax)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x10(%rbp)
mov    0x2ee9(%rip),%rax
mov    %rax,-0x20(%rbp)
lea    -0x20(%rbp),%rdi
lea    -0x10(%rbp),%rsi
call   1030 <psdes@plt>
mov    0x2eb9(%rip),%rax
mov    0x2eba(%rip),%rcx
and    -0x10(%rbp),%rcx
or     %rcx,%rax
mov    %rax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rcx
add    $0x1,%rcx
mov    %rcx,(%rax)
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe60(%rip),%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ran4>:
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%rbx
mov    (%rdi),%rax
test   %rax,%rax
js     1129 <ran4+0x19>
mov    0x2f09(%rip),%rcx
jmp    1142 <ran4+0x32>
neg    %rax
mov    %rax,0x2efd(%rip)
movq   $0x1,(%rbx)
mov    %rax,%rcx
mov    $0x1,%eax
mov    %rax,(%rsp)
mov    %rcx,0x8(%rsp)
lea    0x8(%rsp),%rdi
mov    %rsp,%rsi
call   1030 <psdes@plt>
mov    $0x7fffff,%eax
and    (%rsp),%eax
addq   $0x1,(%rbx)
or     $0x3f800000,%eax
movd   %eax,%xmm0
addss  0xe8b(%rip),%xmm0
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@ran4.idums = internal global i64 0
@ran4.jflone = internal global i64 1065353216
@ran4.jflmsk = internal global i64 8388607
define float @ran4(i64* %0) {
%2 = alloca i64*
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
store i64* %0, i64** %2
%6 = load i64*, i64** %2
%7 = load i64, i64* %6
%8 = icmp slt i64 %7, 0
br i1 %8, label %9, label %14
9: ; preds = %1
%10 = load i64*, i64** %2
%11 = load i64, i64* %10
%12 = sub nsw i64 0, %11
store i64 %12, i64* @ran4.idums
%13 = load i64*, i64** %2
store i64 1, i64* %13
br label %14
14: ; preds = %9, %1
%15 = load i64*, i64** %2
%16 = load i64, i64* %15
store i64 %16, i64* %3
%17 = load i64, i64* @ran4.idums
store i64 %17, i64* %5
%18 = load i64, i64* @ran4.jflone
%19 = load i64, i64* @ran4.jflmsk
%20 = load i64, i64* %3
%21 = and i64 %19, %20
%22 = or i64 %18, %21
store i64 %22, i64* %4
%23 = load i64*, i64** %2
%24 = load i64, i64* %23
%25 = add nsw i64 %24, 1
store i64 %25, i64* %23
%26 = bitcast i64* %4 to float*
%27 = load float, float* %26
%28 = fpext float %27 to double
%29 = fsub double %28, 1.000000e+00
%30 = fptrunc double %29 to float
ret float %30
}

LLVM IR (-O2):
@ran4.idums = internal unnamed_addr global i64 0
define float @ran4(i64* nocapture %0) {
%2 = alloca i64
%3 = alloca i64
%4 = bitcast i64* %2 to i8*
%5 = bitcast i64* %3 to i8*
%6 = load i64, i64* %0
%7 = icmp slt i64 %6, 0
br i1 %7, label %10, label %8
8: ; preds = %1
%9 = load i64, i64* @ran4.idums
br label %12
10: ; preds = %1
%11 = sub nsw i64 0, %6
store i64 %11, i64* @ran4.idums
store i64 1, i64* %0
br label %12
12: ; preds = %8, %10
%13 = phi i64 [ %11, %10 ], [ %9, %8 ]
%14 = phi i64 [ 1, %10 ], [ %6, %8 ]
store i64 %14, i64* %2
store i64 %13, i64* %3
%15 = load i64, i64* %2
%16 = trunc i64 %15 to i32
%17 = and i32 %16, 8388607
%18 = or i32 %17, 1065353216
%19 = bitcast i32 %18 to float
%20 = load i64, i64* %0
%21 = add nsw i64 %20, 1
store i64 %21, i64* %0
%22 = fadd float %19, -1.000000e+00
ret float %22
}