#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 random_number(int);
double random_float(void) {
  return (random_number(10000) / 10000.0 +
          random_number(10000) / (10000.0 * 10000.0) +
          random_number(10000) / (10000.0 * 10000.0 * 10000.0) +
          random_number(10000) / (10000.0 * 10000.0 * 10000.0 * 10000.0));
}


x86 assembly (clang, -O0):
<random_float>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    $0x2710,%edi
call   1030 <random_number@plt>
movsd  0xeee(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movaps %xmm0,%xmm1
movsd  -0x18(%rbp),%xmm0
movsd  0xec3(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movaps %xmm0,%xmm1
movsd  -0x10(%rbp),%xmm0
movsd  0xe94(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movaps %xmm0,%xmm1
movsd  -0x8(%rbp),%xmm0
movsd  0xe65(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<random_float>:
sub    $0x28,%rsp
mov    $0x2710,%edi
call   1030 <random_number@plt>
movapd %xmm0,(%rsp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movapd (%rsp),%xmm1
unpcklpd %xmm0,%xmm1
divpd  0xec2(%rip),%xmm1
movapd %xmm1,(%rsp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movapd %xmm0,0x10(%rsp)
mov    $0x2710,%edi
call   1030 <random_number@plt>
movapd 0x10(%rsp),%xmm1
unpcklpd %xmm0,%xmm1
divpd  0xea1(%rip),%xmm1
movapd (%rsp),%xmm2
movapd %xmm2,%xmm0
unpckhpd %xmm2,%xmm0
addsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
add    $0x28,%rsp
ret

LLVM IR (-O0):
define double @random_float() {
%1 = call double @random_number(i32 10000)
%2 = fdiv double %1, 1.000000e+04
%3 = call double @random_number(i32 10000)
%4 = fdiv double %3, 1.000000e+08
%5 = fadd double %2, %4
%6 = call double @random_number(i32 10000)
%7 = fdiv double %6, 1.000000e+12
%8 = fadd double %5, %7
%9 = call double @random_number(i32 10000)
%10 = fdiv double %9, 1.000000e+16
%11 = fadd double %8, %10
ret double %11
}

LLVM IR (-O2):
define double @random_float() {
%1 = tail call double @random_number(i32 10000)
%2 = tail call double @random_number(i32 10000)
%3 = insertelement <2 x double> poison, double %1, i64 0
%4 = insertelement <2 x double> %3, double %2, i64 1
%5 = fdiv <2 x double> %4, <double 1.000000e+04, double 1.000000e+08>
%6 = shufflevector <2 x double> %5, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%7 = fadd <2 x double> %5, %6
%8 = tail call double @random_number(i32 10000)
%9 = tail call double @random_number(i32 10000)
%10 = insertelement <2 x double> poison, double %8, i64 0
%11 = insertelement <2 x double> %10, double %9, i64 1
%12 = fdiv <2 x double> %11, <double 1.000000e+12, double 1.000000e+16>
%13 = fadd <2 x double> %7, %12
%14 = shufflevector <2 x double> %12, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%15 = fadd <2 x double> %13, %14
%16 = extractelement <2 x double> %15, i64 0
ret double %16
}