#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 generateRandom();
scalar_t__ isBetween(double, double, double);
char createNucleotide(double adeninePercentage, double guaninePercentage,
                      double cytosinePercentage, double thyminePercentage) {
  char nucleotide;
  double random = generateRandom();
  if (isBetween(random, 0, adeninePercentage)) {
    nucleotide = 'A';
  } else if (isBetween(random, adeninePercentage,
                       adeninePercentage + guaninePercentage)) {
    nucleotide = 'G';
  } else if (isBetween(random, adeninePercentage + guaninePercentage,
                       adeninePercentage + guaninePercentage +
                           cytosinePercentage)) {
    nucleotide = 'C';
  } else if (isBetween(random,
                       adeninePercentage + guaninePercentage +
                           cytosinePercentage,
                       adeninePercentage + guaninePercentage +
                           cytosinePercentage + thyminePercentage)) {
    nucleotide = 'T';
  }
  return nucleotide;
}


x86 assembly (clang, -O0):
<createNucleotide>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
movsd  %xmm3,-0x20(%rbp)
mov    $0x0,%al
call   1030 <generateRandom@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm2
xorps  %xmm1,%xmm1
call   1040 <isBetween@plt>
cmp    $0x0,%rax
je     116d <createNucleotide+0x4d>
movb   $0x41,-0x21(%rbp)
jmp    1219 <createNucleotide+0xf9>
movsd  -0x30(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm1
movsd  -0x8(%rbp),%xmm2
addsd  -0x10(%rbp),%xmm2
call   1040 <isBetween@plt>
cmp    $0x0,%rax
je     1199 <createNucleotide+0x79>
movb   $0x47,-0x21(%rbp)
jmp    1214 <createNucleotide+0xf4>
movsd  -0x30(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm1
addsd  -0x10(%rbp),%xmm1
movsd  -0x8(%rbp),%xmm2
addsd  -0x10(%rbp),%xmm2
addsd  -0x18(%rbp),%xmm2
call   1040 <isBetween@plt>
cmp    $0x0,%rax
je     11cf <createNucleotide+0xaf>
movb   $0x43,-0x21(%rbp)
jmp    120f <createNucleotide+0xef>
movsd  -0x30(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm1
addsd  -0x10(%rbp),%xmm1
addsd  -0x18(%rbp),%xmm1
movsd  -0x8(%rbp),%xmm2
addsd  -0x10(%rbp),%xmm2
addsd  -0x18(%rbp),%xmm2
addsd  -0x20(%rbp),%xmm2
call   1040 <isBetween@plt>
cmp    $0x0,%rax
je     120a <createNucleotide+0xea>
movb   $0x54,-0x21(%rbp)
jmp    120f <createNucleotide+0xef>
jmp    1214 <createNucleotide+0xf4>
jmp    1219 <createNucleotide+0xf9>
movsbl -0x21(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<createNucleotide>:
sub    $0x28,%rsp
movsd  %xmm3,0x20(%rsp)
movsd  %xmm2,(%rsp)
movsd  %xmm1,0x10(%rsp)
movsd  %xmm0,0x18(%rsp)
xor    %eax,%eax
call   1030 <generateRandom@plt>
xorpd  %xmm1,%xmm1
movsd  %xmm0,0x8(%rsp)
movsd  0x18(%rsp),%xmm2
call   1040 <isBetween@plt>
mov    %rax,%rcx
mov    $0x41,%al
test   %rcx,%rcx
je     1166 <createNucleotide+0x46>
add    $0x28,%rsp
ret
movsd  0x10(%rsp),%xmm2
movsd  0x18(%rsp),%xmm1
addsd  %xmm1,%xmm2
movsd  0x8(%rsp),%xmm0
movsd  %xmm2,0x10(%rsp)
call   1040 <isBetween@plt>
mov    %rax,%rcx
mov    $0x47,%al
test   %rcx,%rcx
jne    1161 <createNucleotide+0x41>
movsd  (%rsp),%xmm2
movsd  0x10(%rsp),%xmm1
addsd  %xmm1,%xmm2
movsd  0x8(%rsp),%xmm0
movsd  %xmm2,(%rsp)
call   1040 <isBetween@plt>
mov    %rax,%rcx
mov    $0x43,%al
test   %rcx,%rcx
jne    1161 <createNucleotide+0x41>
movsd  0x20(%rsp),%xmm2
movsd  (%rsp),%xmm1
addsd  %xmm1,%xmm2
movsd  0x8(%rsp),%xmm0
call   1040 <isBetween@plt>
mov    $0x54,%al
add    $0x28,%rsp
ret

LLVM IR (-O0):
define signext i8 @createNucleotide(double %0, double %1, double %2, double %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca i8
%10 = alloca double
store double %0, double* %5
store double %1, double* %6
store double %2, double* %7
store double %3, double* %8
%11 = call double (...) @generateRandom()
store double %11, double* %10
%12 = load double, double* %10
%13 = load double, double* %5
%14 = call i64 @isBetween(double %12, double 0.000000e+00, double %13)
%15 = icmp ne i64 %14, 0
br i1 %15, label %16, label %17
16: ; preds = %4
store i8 65, i8* %9
br label %59
17: ; preds = %4
%18 = load double, double* %10
%19 = load double, double* %5
%20 = load double, double* %5
%21 = load double, double* %6
%22 = fadd double %20, %21
%23 = call i64 @isBetween(double %18, double %19, double %22)
%24 = icmp ne i64 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %17
store i8 71, i8* %9
br label %58
26: ; preds = %17
%27 = load double, double* %10
%28 = load double, double* %5
%29 = load double, double* %6
%30 = fadd double %28, %29
%31 = load double, double* %5
%32 = load double, double* %6
%33 = fadd double %31, %32
%34 = load double, double* %7
%35 = fadd double %33, %34
%36 = call i64 @isBetween(double %27, double %30, double %35)
%37 = icmp ne i64 %36, 0
br i1 %37, label %38, label %39
38: ; preds = %26
store i8 67, i8* %9
br label %57
39: ; preds = %26
%40 = load double, double* %10
%41 = load double, double* %5
%42 = load double, double* %6
%43 = fadd double %41, %42
%44 = load double, double* %7
%45 = fadd double %43, %44
%46 = load double, double* %5
%47 = load double, double* %6
%48 = fadd double %46, %47
%49 = load double, double* %7
%50 = fadd double %48, %49
%51 = load double, double* %8
%52 = fadd double %50, %51
%53 = call i64 @isBetween(double %40, double %45, double %52)
%54 = icmp ne i64 %53, 0
br i1 %54, label %55, label %56
55: ; preds = %39
store i8 84, i8* %9
br label %56
56: ; preds = %55, %39
br label %57
57: ; preds = %56, %38
br label %58
58: ; preds = %57, %25
br label %59
59: ; preds = %58, %16
%60 = load i8, i8* %9
ret i8 %60
}

LLVM IR (-O2):
define signext i8 @createNucleotide(double %0, double %1, double %2, double %3) {
%5 = tail call double (...) @generateRandom()
%6 = tail call i64 @isBetween(double %5, double 0.000000e+00, double %0)
%7 = icmp eq i64 %6, 0
br i1 %7, label %8, label %19
8: ; preds = %4
%9 = fadd double %0, %1
%10 = tail call i64 @isBetween(double %5, double %0, double %9)
%11 = icmp eq i64 %10, 0
br i1 %11, label %12, label %19
12: ; preds = %8
%13 = fadd double %9, %2
%14 = tail call i64 @isBetween(double %5, double %9, double %13)
%15 = icmp eq i64 %14, 0
br i1 %15, label %16, label %19
16: ; preds = %12
%17 = fadd double %13, %3
%18 = tail call i64 @isBetween(double %5, double %13, double %17)
br label %19
19: ; preds = %16, %12, %8, %4
%20 = phi i8 [ 65, %4 ], [ 71, %8 ], [ 67, %12 ], [ 84, %16 ]
ret i8 %20
}