double gen_rand(void) {
  unsigned long y;
  static int k = 0;
  static unsigned long x[25] = {
      0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23,
      0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825,
      0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f,
      0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9,
      0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb};
  static unsigned long mag01[2] = {0x0, 0x8ebfd028};
  if (k == 25) {
    int kk;
    for (kk = 0; kk < 25 - 7; kk++) {
      x[kk] = x[kk + 7] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2];
    }
    for (; kk < 25; kk++) {
      x[kk] = x[kk + (7 - 25)] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2];
    }
    k = 0;
  }
  y = x[k];
  y ^= (y << 7) & 0x2b5b2500;
  y ^= (y << 15) & 0xdb8b0000;
  y &= 0xffffffff;
  y ^= (y >> 16);
  k++;
  return ((double)y / (unsigned long)0xffffffff);
}


x86 assembly (clang, -O0):
<gen_rand>:
push   %rbp
mov    %rsp,%rbp
cmpl   $0x19,0x3009(%rip)
jne    1205 <gen_rand+0x105>
movl   $0x0,-0xc(%rbp)
cmpl   $0x12,-0xc(%rbp)
jge    1187 <gen_rand+0x87>
mov    -0xc(%rbp),%eax
add    $0x7,%eax
movslq %eax,%rcx
lea    0x2efe(%rip),%rax
mov    (%rax,%rcx,8),%rdx
movslq -0xc(%rbp),%rcx
lea    0x2eef(%rip),%rax
mov    (%rax,%rcx,8),%rax
shr    $0x1,%rax
xor    %rax,%rdx
movslq -0xc(%rbp),%rcx
lea    0x2ed9(%rip),%rax
mov    (%rax,%rcx,8),%rcx
and    $0x1,%rcx
lea    0x2f9a(%rip),%rax
xor    (%rax,%rcx,8),%rdx
movslq -0xc(%rbp),%rcx
lea    0x2ebb(%rip),%rax
mov    %rdx,(%rax,%rcx,8)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1118 <gen_rand+0x18>
jmp    118c <gen_rand+0x8c>
cmpl   $0x19,-0xc(%rbp)
jge    11fb <gen_rand+0xfb>
mov    -0xc(%rbp),%eax
add    $0xffffffee,%eax
movslq %eax,%rcx
lea    0x2e8a(%rip),%rax
mov    (%rax,%rcx,8),%rdx
movslq -0xc(%rbp),%rcx
lea    0x2e7b(%rip),%rax
mov    (%rax,%rcx,8),%rax
shr    $0x1,%rax
xor    %rax,%rdx
movslq -0xc(%rbp),%rcx
lea    0x2e65(%rip),%rax
mov    (%rax,%rcx,8),%rcx
and    $0x1,%rcx
lea    0x2f26(%rip),%rax
xor    (%rax,%rcx,8),%rdx
movslq -0xc(%rbp),%rcx
lea    0x2e47(%rip),%rax
mov    %rdx,(%rax,%rcx,8)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    118c <gen_rand+0x8c>
movl   $0x0,0x2f0f(%rip)
movslq 0x2f08(%rip),%rcx
lea    0x2e1d(%rip),%rax
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %eax,%edx
shl    $0x7,%edx
mov    %edx,%ecx
and    $0x2b5b2500,%ecx
xor    %rcx,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %eax,%ecx
and    $0x1b716,%ecx
shl    $0xf,%rcx
xor    %rcx,%rax
mov    %rax,-0x8(%rbp)
movl   $0x0,-0x4(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
shr    $0x10,%rcx
xor    %rcx,%rax
mov    %rax,-0x8(%rbp)
mov    0x2eab(%rip),%eax
add    $0x1,%eax
mov    %eax,0x2ea2(%rip)
movaps 0xd97(%rip),%xmm1
movq   -0x8(%rbp),%xmm0
punpckldq %xmm1,%xmm0
movapd 0xd96(%rip),%xmm1
subpd  %xmm1,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
movsd  0xd5f(%rip),%xmm1
divsd  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<gen_rand>:
mov    0x2ff6(%rip),%eax
cmp    $0x19,%eax
jne    1234 <gen_rand+0x134>
xor    %ecx,%ecx
lea    0x2f18(%rip),%rdx
lea    0xef1(%rip),%rax
nop
mov    (%rdx,%rcx,8),%rsi
mov    %rsi,%rdi
shr    %rdi
xor    0x38(%rdx,%rcx,8),%rdi
and    $0x1,%esi
xor    (%rax,%rsi,8),%rdi
mov    %rdi,(%rdx,%rcx,8)
add    $0x1,%rcx
cmp    $0x12,%rcx
jne    1120 <gen_rand+0x20>
mov    0x2f75(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2ed8(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2f5a(%rip)
mov    0x2f5b(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2ebe(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2f40(%rip)
mov    0x2f41(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2ea4(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2f26(%rip)
mov    0x2f27(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2e8a(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2f0c(%rip)
mov    0x2f0d(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2e70(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2ef2(%rip)
mov    0x2ef3(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2e56(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2ed8(%rip)
mov    0x2ed9(%rip),%rcx
mov    %rcx,%rdx
shr    %rdx
xor    0x2e3c(%rip),%rdx
and    $0x1,%ecx
xor    (%rax,%rcx,8),%rdx
mov    %rdx,0x2ebe(%rip)
xor    %eax,%eax
cltq
lea    0x2df3(%rip),%rcx
mov    (%rcx,%rax,8),%rcx
mov    %ecx,%edx
shl    $0x7,%edx
and    $0x2b5b2500,%edx
xor    %rcx,%rdx
mov    %edx,%ecx
and    $0x1b716,%edx
shl    $0xf,%rdx
xor    %rdx,%rcx
mov    %rcx,%rdx
shr    $0x10,%rdx
xor    %rcx,%rdx
add    $0x1,%eax
mov    %eax,0x2e8b(%rip)
cvtsi2sd %rdx,%xmm0
divsd  0xd82(%rip),%xmm0
ret

LLVM IR (-O0):
@gen_rand.k = internal global i32 0
@gen_rand.x = internal global [25 x i64] [i64 2515684779, i64 191386133, i64 3882666727, i64 2940125753, i64 1902095651, i64 614830253, i64 1776596463, i64 3208995137, i64 2528910203, i64 2814244901, i64 3252581815, i64 2287512009, i64 766015123, i64 3059218909, i64 4292643487, i64 2166479473, i64 2340568779, i64 2287797749, i64 1310772551, i64 1520096729, i64 1361841155, i64 3934616781, i64 1287770895, i64 2291247265, i64 2797054683]
@gen_rand.mag01 = internal global [2 x i64] [i64 0, i64 2394935336]
define double @gen_rand() {
%1 = alloca i64
%2 = alloca i32
%3 = load i32, i32* @gen_rand.k
%4 = icmp eq i32 %3, 25
br i1 %4, label %5, label %66
5: ; preds = %0
store i32 0, i32* %2
br label %6
6: ; preds = %32, %5
%7 = load i32, i32* %2
%8 = icmp slt i32 %7, 18
br i1 %8, label %9, label %35
9: ; preds = %6
%10 = load i32, i32* %2
%11 = add nsw i32 %10, 7
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %12
%14 = load i64, i64* %13
%15 = load i32, i32* %2
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %16
%18 = load i64, i64* %17
%19 = lshr i64 %18, 1
%20 = xor i64 %14, %19
%21 = load i32, i32* %2
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %22
%24 = load i64, i64* %23
%25 = urem i64 %24, 2
%26 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %25
%27 = load i64, i64* %26
%28 = xor i64 %20, %27
%29 = load i32, i32* %2
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %30
store i64 %28, i64* %31
br label %32
32: ; preds = %9
%33 = load i32, i32* %2
%34 = add nsw i32 %33, 1
store i32 %34, i32* %2
br label %6
35: ; preds = %6
br label %36
36: ; preds = %62, %35
%37 = load i32, i32* %2
%38 = icmp slt i32 %37, 25
br i1 %38, label %39, label %65
39: ; preds = %36
%40 = load i32, i32* %2
%41 = add nsw i32 %40, -18
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %42
%44 = load i64, i64* %43
%45 = load i32, i32* %2
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %46
%48 = load i64, i64* %47
%49 = lshr i64 %48, 1
%50 = xor i64 %44, %49
%51 = load i32, i32* %2
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %52
%54 = load i64, i64* %53
%55 = urem i64 %54, 2
%56 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %55
%57 = load i64, i64* %56
%58 = xor i64 %50, %57
%59 = load i32, i32* %2
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %60
store i64 %58, i64* %61
br label %62
62: ; preds = %39
%63 = load i32, i32* %2
%64 = add nsw i32 %63, 1
store i32 %64, i32* %2
br label %36
65: ; preds = %36
store i32 0, i32* @gen_rand.k
br label %66
66: ; preds = %65, %0
%67 = load i32, i32* @gen_rand.k
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %68
%70 = load i64, i64* %69
store i64 %70, i64* %1
%71 = load i64, i64* %1
%72 = shl i64 %71, 7
%73 = and i64 %72, 727393536
%74 = load i64, i64* %1
%75 = xor i64 %74, %73
store i64 %75, i64* %1
%76 = load i64, i64* %1
%77 = shl i64 %76, 15
%78 = and i64 %77, 3683319808
%79 = load i64, i64* %1
%80 = xor i64 %79, %78
store i64 %80, i64* %1
%81 = load i64, i64* %1
%82 = and i64 %81, 4294967295
store i64 %82, i64* %1
%83 = load i64, i64* %1
%84 = lshr i64 %83, 16
%85 = load i64, i64* %1
%86 = xor i64 %85, %84
store i64 %86, i64* %1
%87 = load i32, i32* @gen_rand.k
%88 = add nsw i32 %87, 1
store i32 %88, i32* @gen_rand.k
%89 = load i64, i64* %1
%90 = uitofp i64 %89 to double
%91 = fdiv double %90, 0x41EFFFFFFFE00000
ret double %91
}

LLVM IR (-O2):
@gen_rand.k = internal unnamed_addr global i32 0
@gen_rand.x = internal unnamed_addr global [25 x i64] [i64 2515684779, i64 191386133, i64 3882666727, i64 2940125753, i64 1902095651, i64 614830253, i64 1776596463, i64 3208995137, i64 2528910203, i64 2814244901, i64 3252581815, i64 2287512009, i64 766015123, i64 3059218909, i64 4292643487, i64 2166479473, i64 2340568779, i64 2287797749, i64 1310772551, i64 1520096729, i64 1361841155, i64 3934616781, i64 1287770895, i64 2291247265, i64 2797054683]
@gen_rand.mag01 = internal unnamed_addr constant [2 x i64] [i64 0, i64 2394935336]
define double @gen_rand() {
%1 = load i32, i32* @gen_rand.k
%2 = icmp eq i32 %1, 25
br i1 %2, label %3, label %75
3: ; preds = %0, %3
%4 = phi i64 [ %16, %3 ], [ 0, %0 ]
%5 = add nuw nsw i64 %4, 7
%6 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %5
%7 = load i64, i64* %6
%8 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %4
%9 = load i64, i64* %8
%10 = lshr i64 %9, 1
%11 = xor i64 %10, %7
%12 = and i64 %9, 1
%13 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %12
%14 = load i64, i64* %13
%15 = xor i64 %11, %14
store i64 %15, i64* %8
%16 = add nuw nsw i64 %4, 1
%17 = icmp eq i64 %16, 18
br i1 %17, label %18, label %3
18: ; preds = %3
%19 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 0)
%20 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 18)
%21 = lshr i64 %20, 1
%22 = xor i64 %21, %19
%23 = and i64 %20, 1
%24 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %23
%25 = load i64, i64* %24
%26 = xor i64 %22, %25
store i64 %26, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 18)
%27 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 1)
%28 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 19)
%29 = lshr i64 %28, 1
%30 = xor i64 %29, %27
%31 = and i64 %28, 1
%32 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %31
%33 = load i64, i64* %32
%34 = xor i64 %30, %33
store i64 %34, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 19)
%35 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 2)
%36 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 20)
%37 = lshr i64 %36, 1
%38 = xor i64 %37, %35
%39 = and i64 %36, 1
%40 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %39
%41 = load i64, i64* %40
%42 = xor i64 %38, %41
store i64 %42, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 20)
%43 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 3)
%44 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 21)
%45 = lshr i64 %44, 1
%46 = xor i64 %45, %43
%47 = and i64 %44, 1
%48 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %47
%49 = load i64, i64* %48
%50 = xor i64 %46, %49
store i64 %50, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 21)
%51 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 4)
%52 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 22)
%53 = lshr i64 %52, 1
%54 = xor i64 %53, %51
%55 = and i64 %52, 1
%56 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %55
%57 = load i64, i64* %56
%58 = xor i64 %54, %57
store i64 %58, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 22)
%59 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 5)
%60 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 23)
%61 = lshr i64 %60, 1
%62 = xor i64 %61, %59
%63 = and i64 %60, 1
%64 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %63
%65 = load i64, i64* %64
%66 = xor i64 %62, %65
store i64 %66, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 23)
%67 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 6)
%68 = load i64, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 24)
%69 = lshr i64 %68, 1
%70 = xor i64 %69, %67
%71 = and i64 %68, 1
%72 = getelementptr inbounds [2 x i64], [2 x i64]* @gen_rand.mag01, i64 0, i64 %71
%73 = load i64, i64* %72
%74 = xor i64 %70, %73
store i64 %74, i64* getelementptr inbounds ([25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 24)
br label %75
75: ; preds = %18, %0
%76 = phi i32 [ 0, %18 ], [ %1, %0 ]
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds [25 x i64], [25 x i64]* @gen_rand.x, i64 0, i64 %77
%79 = load i64, i64* %78
%80 = shl i64 %79, 7
%81 = and i64 %80, 727393536
%82 = xor i64 %81, %79
%83 = shl i64 %82, 15
%84 = and i64 %83, 3683319808
%85 = and i64 %82, 4294967295
%86 = xor i64 %84, %85
%87 = lshr i64 %86, 16
%88 = xor i64 %87, %86
%89 = add nsw i32 %76, 1
store i32 %89, i32* @gen_rand.k
%90 = uitofp i64 %88 to double
%91 = fdiv double %90, 0x41EFFFFFFFE00000
ret double %91
}