double ran0(long *idum) {
  long k;
  double ans;
  *idum ^= 123459876;
  k = (*idum) / 127773;
  *idum = 16807 * (*idum - k * 127773) - 2836 * k;
  if (*idum < 0)
    *idum += 2147483647;
  ans = (1.0 / 2147483647) * (*idum);
  *idum ^= 123459876;
  return ans;
}


x86 assembly (clang, -O0):
<ran0>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rcx
xor    $0x75bd924,%rcx
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    $0x1f31d,%ecx
cqto
idiv   %rcx
mov    %rax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
imul   $0x1f31d,-0x10(%rbp),%rcx
sub    %rcx,%rax
imul   $0x41a7,%rax,%rcx
imul   $0xb14,-0x10(%rbp),%rax
sub    %rax,%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
cmpq   $0x0,(%rax)
jge    1178 <ran0+0x78>
mov    -0x8(%rbp),%rax
mov    (%rax),%rcx
add    $0x7fffffff,%rcx
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
cvtsi2sdq (%rax),%xmm1
movsd  0xe77(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rcx
xor    $0x75bd924,%rcx
mov    %rcx,(%rax)
movsd  -0x18(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<ran0>:
mov    $0x75bd924,%ecx
xor    (%rdi),%rcx
movabs $0x41a705af1fe3fb79,%rdx
05 a7 41
mov    %rcx,%rax
imul   %rdx
mov    %rdx,%rax
shr    $0x3f,%rax
sar    $0xf,%rdx
add    %rax,%rdx
imul   $0xfffffffffffe0ce3,%rdx,%rax
add    %rcx,%rax
imul   $0x41a7,%rax,%rax
imul   $0xfffffffffffff4ec,%rdx,%rcx
lea    (%rax,%rcx,1),%rdx
add    $0x7fffffff,%rdx
add    %rcx,%rax
cmovns %rax,%rdx
cvtsi2sd %rdx,%xmm0
mulsd  0xea3(%rip),%xmm0
xor    $0x75bd924,%rdx
mov    %rdx,(%rdi)
ret

LLVM IR (-O0):
define double @ran0(i64* %0) {
%2 = alloca i64*
%3 = alloca i64
%4 = alloca double
store i64* %0, i64** %2
%5 = load i64*, i64** %2
%6 = load i64, i64* %5
%7 = xor i64 %6, 123459876
store i64 %7, i64* %5
%8 = load i64*, i64** %2
%9 = load i64, i64* %8
%10 = sdiv i64 %9, 127773
store i64 %10, i64* %3
%11 = load i64*, i64** %2
%12 = load i64, i64* %11
%13 = load i64, i64* %3
%14 = mul nsw i64 %13, 127773
%15 = sub nsw i64 %12, %14
%16 = mul nsw i64 16807, %15
%17 = load i64, i64* %3
%18 = mul nsw i64 2836, %17
%19 = sub nsw i64 %16, %18
%20 = load i64*, i64** %2
store i64 %19, i64* %20
%21 = load i64*, i64** %2
%22 = load i64, i64* %21
%23 = icmp slt i64 %22, 0
br i1 %23, label %24, label %28
24: ; preds = %1
%25 = load i64*, i64** %2
%26 = load i64, i64* %25
%27 = add nsw i64 %26, 2147483647
store i64 %27, i64* %25
br label %28
28: ; preds = %24, %1
%29 = load i64*, i64** %2
%30 = load i64, i64* %29
%31 = sitofp i64 %30 to double
%32 = fmul double 0x3E00000000200000, %31
store double %32, double* %4
%33 = load i64*, i64** %2
%34 = load i64, i64* %33
%35 = xor i64 %34, 123459876
store i64 %35, i64* %33
%36 = load double, double* %4
ret double %36
}

LLVM IR (-O2):
define double @ran0(i64* nocapture %0) {
%2 = load i64, i64* %0
%3 = xor i64 %2, 123459876
%4 = sdiv i64 %3, 127773
%5 = mul nsw i64 %4, -127773
%6 = add i64 %5, %3
%7 = mul nsw i64 %6, 16807
%8 = mul nsw i64 %4, -2836
%9 = add i64 %7, %8
%10 = icmp slt i64 %9, 0
%11 = add nsw i64 %9, 2147483647
%12 = select i1 %10, i64 %11, i64 %9
%13 = sitofp i64 %12 to double
%14 = fmul double %13, 0x3E00000000200000
%15 = xor i64 %12, 123459876
store i64 %15, i64* %0
ret double %14
}