#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 */
typedef scalar_t__ clock_t;
typedef int /*<<< orphan*/ cl_program;
typedef int /*<<< orphan*/ cl_mem;
typedef int /*<<< orphan*/ cl_kernel;
typedef int /*<<< orphan*/ cl_float4;
typedef int /*<<< orphan*/ cl_device_id;
typedef int /*<<< orphan*/ cl_context;
typedef int /*<<< orphan*/ cl_command_queue;
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
scalar_t__ EOF;
int /*<<< orphan*/ EXIT_FAILURE;
float FLT_MAX;
float RAND_MAX;
int /*<<< orphan*/ bucketSort(float *, float *, int, int *, int *, float, float,
                              unsigned int *);
scalar_t__ clock();
int /*<<< orphan*/ exit(int /*<<< orphan*/);
int /*<<< orphan*/ fclose(int /*<<< orphan*/ *);
int /*<<< orphan*/ finish_bucketsort();
int /*<<< orphan*/ finish_mergesort();
float fmaxf(float, float);
float fminf(float, float);
int /*<<< orphan*/ *fopen(char const *, char *);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/ *, char *, float);
scalar_t__ fscanf(int /*<<< orphan*/ *, char *, float *);
double getBucketTime();
int /*<<< orphan*/ init_bucketsort(int);
int /*<<< orphan*/ init_mergesort(int);
scalar_t__ malloc(int);
int /*<<< orphan*/ memcpy(float *, float *, int);
int /*<<< orphan*/ printf(char *, ...);
scalar_t__ rand();
int /*<<< orphan*/ *runMergeSort(int, int, int /*<<< orphan*/ *,
                                 int /*<<< orphan*/ *, int *, int *,
                                 unsigned int *);
scalar_t__ strcmp(char *, char *);
int main(int argc, char **argv) {
  int err;
  unsigned int correct;
  size_t global;
  size_t local;
  unsigned int *results;
  cl_device_id device_id;
  cl_context context;
  cl_command_queue commands;
  cl_program program;
  cl_kernel kernel;
  cl_mem input;
  cl_mem output;
  int numElements = 0;
  if (strcmp(argv[1], "r") == 0) {
    numElements = (1000000);
  } else {
    FILE *fp;
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
      printf("Error reading file \n");
      exit(EXIT_FAILURE);
    }
    int count = 0;
    float c;
    while (fscanf(fp, "%f", &c) != EOF) {
      count++;
    }
    fclose(fp);
    numElements = count;
  }
  printf("Sorting list of %d floats.\n", numElements);
  int mem_size = (numElements + ((1 << 10) * 4)) * sizeof(float);
  float *cpu_idata = (float *)malloc(mem_size);
  float *cpu_odata = (float *)malloc(mem_size);
  float *d_output = (float *)malloc(mem_size);
  float *gpu_odata = (float *)malloc(mem_size);
  float datamin = FLT_MAX;
  float datamax = -FLT_MAX;
  if (strcmp(argv[1], "r") == 0) {
    for (int i = 0; i < numElements; i++) {
      cpu_idata[i] = ((float)rand() / RAND_MAX);
      datamin = fminf(cpu_idata[i], datamin);
      datamax = fmaxf(cpu_idata[i], datamax);
    }
  } else {
    FILE *fp;
    fp = fopen(argv[1], "r");
    for (int i = 0; i < numElements; i++) {
      fscanf(fp, "%f", &cpu_idata[i]);
      datamin = fminf(cpu_idata[i], datamin);
      datamax = fmaxf(cpu_idata[i], datamax);
    }
  }
  FILE *tp;
  const char filename2[] = "./hybridinput.txt";
  tp = fopen(filename2, "w");
  for (int i = 0; i < (1000000); i++) {
    fprintf(tp, "%f ", cpu_idata[i]);
  }
  fclose(tp);
  memcpy(cpu_odata, cpu_idata, mem_size);
  clock_t gpu_start = clock();
  init_bucketsort(numElements);
  int *sizes = (int *)malloc((1 << 10) * sizeof(int));
  int *nullElements = (int *)malloc((1 << 10) * sizeof(int));
  unsigned int *origOffsets =
      (unsigned int *)malloc(((1 << 10) + 1) * sizeof(int));
  clock_t bucketsort_start = clock();
  bucketSort(cpu_idata, d_output, numElements, sizes, nullElements, datamin,
             datamax, origOffsets);
  clock_t bucketsort_diff = clock() - bucketsort_start;
  finish_bucketsort();
  double bucketTime = getBucketTime();
  cl_float4 *d_origList = (cl_float4 *)d_output;
  cl_float4 *d_resultList = (cl_float4 *)cpu_idata;
  int newlistsize = 0;
  for (int i = 0; i < (1 << 10); i++) {
    newlistsize += sizes[i] * 4;
  }
  init_mergesort(newlistsize);
  clock_t mergesort_start = clock();
  cl_float4 *mergeresult =
      runMergeSort(newlistsize, (1 << 10), d_origList, d_resultList, sizes,
                   nullElements, origOffsets);
  clock_t mergesort_diff = clock() - mergesort_start;
  finish_mergesort();
  gpu_odata = (float *)mergeresult;
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x150,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xdb1(%rip),%rsi
call   10a0 <strcmp@plt>
cmp    $0x0,%rax
jne    126a <main+0x4a>
movl   $0xf4240,-0x50(%rbp)
jmp    12f1 <main+0xd1>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xd87(%rip),%rsi
call   1110 <fopen@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
jne    12a9 <main+0x89>
lea    0xd6e(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
mov    0x2d26(%rip),%rax
mov    (%rax),%edi
call   1120 <exit@plt>
movl   $0x0,-0x5c(%rbp)
mov    -0x58(%rbp),%rdi
lea    0xd5c(%rip),%rsi
lea    -0x60(%rbp),%rdx
call   1060 <fscanf@plt>
mov    0x2d1d(%rip),%rcx
cmp    (%rcx),%rax
je     12e2 <main+0xc2>
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    12b0 <main+0x90>
mov    -0x58(%rbp),%rdi
call   1040 <fclose@plt>
mov    -0x5c(%rbp),%eax
mov    %eax,-0x50(%rbp)
mov    -0x50(%rbp),%esi
lea    0xd1f(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
mov    -0x50(%rbp),%eax
add    $0x1000,%eax
cltq
shl    $0x2,%rax
mov    %eax,-0x64(%rbp)
mov    -0x64(%rbp),%edi
call   10d0 <malloc@plt>
mov    %rax,-0x70(%rbp)
mov    -0x64(%rbp),%edi
call   10d0 <malloc@plt>
mov    %rax,-0x78(%rbp)
mov    -0x64(%rbp),%edi
call   10d0 <malloc@plt>
mov    %rax,-0x80(%rbp)
mov    -0x64(%rbp),%edi
call   10d0 <malloc@plt>
mov    %rax,-0x88(%rbp)
mov    0x2c8b(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x8c(%rbp)
ff
mov    0x2c78(%rip),%rax
movss  (%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x90(%rbp)
ff
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xc78(%rip),%rsi
call   10a0 <strcmp@plt>
cmp    $0x0,%rax
jne    146c <main+0x24c>
movl   $0x0,-0x94(%rbp)
mov    -0x94(%rbp),%eax
cmp    -0x50(%rbp),%eax
jge    1467 <main+0x247>
mov    $0x0,%al
call   1140 <rand@plt>
cvtsi2ss %rax,%xmm0
mov    0x2c1d(%rip),%rax
divss  (%rax),%xmm0
mov    -0x70(%rbp),%rax
movslq -0x94(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x70(%rbp),%rax
movslq -0x94(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
movss  -0x8c(%rbp),%xmm2
ff
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordss %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
minss  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movss  %xmm0,-0x8c(%rbp)
ff
mov    -0x70(%rbp),%rax
movslq -0x94(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
movss  -0x90(%rbp),%xmm2
ff
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordss %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
maxss  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movss  %xmm0,-0x90(%rbp)
ff
mov    -0x94(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x94(%rbp)
jmp    13a1 <main+0x181>
jmp    155a <main+0x33a>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xb85(%rip),%rsi
call   1110 <fopen@plt>
mov    %rax,-0xa0(%rbp)
movl   $0x0,-0xa4(%rbp)
mov    -0xa4(%rbp),%eax
cmp    -0x50(%rbp),%eax
jge    1555 <main+0x335>
mov    -0xa0(%rbp),%rdi
mov    -0x70(%rbp),%rdx
movslq -0xa4(%rbp),%rax
shl    $0x2,%rax
add    %rax,%rdx
lea    0xb57(%rip),%rsi
call   1060 <fscanf@plt>
mov    -0x70(%rbp),%rax
movslq -0xa4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
movss  -0x8c(%rbp),%xmm2
ff
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordss %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
minss  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movss  %xmm0,-0x8c(%rbp)
ff
mov    -0x70(%rbp),%rax
movslq -0xa4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
movss  -0x90(%rbp),%xmm2
ff
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordss %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
maxss  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movss  %xmm0,-0x90(%rbp)
ff
mov    -0xa4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xa4(%rbp)
jmp    1491 <main+0x271>
jmp    155a <main+0x33a>
mov    0xadf(%rip),%rax
mov    %rax,-0xd0(%rbp)
mov    0xad9(%rip),%rax
mov    %rax,-0xc8(%rbp)
mov    0xad3(%rip),%ax
mov    %ax,-0xc0(%rbp)
lea    -0xd0(%rbp),%rdi
lea    0xaa4(%rip),%rsi
call   1110 <fopen@plt>
mov    %rax,-0xb0(%rbp)
movl   $0x0,-0xd4(%rbp)
cmpl   $0xf4240,-0xd4(%rbp)
jge    15ef <main+0x3cf>
mov    -0xb0(%rbp),%rdi
mov    -0x70(%rbp),%rax
movslq -0xd4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
lea    0xa62(%rip),%rsi
call   10b0 <fprintf@plt>
mov    -0xd4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xd4(%rbp)
jmp    15a8 <main+0x388>
mov    -0xb0(%rbp),%rdi
call   1040 <fclose@plt>
mov    -0x78(%rbp),%rdi
mov    -0x70(%rbp),%rsi
mov    -0x64(%rbp),%edx
call   10c0 <memcpy@plt>
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0xe0(%rbp)
mov    -0x50(%rbp),%edi
call   10e0 <init_bucketsort@plt>
mov    $0x1000,%edi
call   10d0 <malloc@plt>
mov    %rax,-0xe8(%rbp)
mov    $0x1000,%edi
call   10d0 <malloc@plt>
mov    %rax,-0xf0(%rbp)
mov    $0x1004,%edi
call   10d0 <malloc@plt>
mov    %rax,-0xf8(%rbp)
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x100(%rbp)
mov    -0x70(%rbp),%rdi
mov    -0x80(%rbp),%rsi
mov    -0x50(%rbp),%edx
mov    -0xe8(%rbp),%rcx
mov    -0xf0(%rbp),%r8
movss  -0x8c(%rbp),%xmm0
ff
movss  -0x90(%rbp),%xmm1
ff
mov    -0xf8(%rbp),%r9
call   1100 <bucketSort@plt>
mov    $0x0,%al
call   1030 <clock@plt>
sub    -0x100(%rbp),%rax
mov    %rax,-0x108(%rbp)
mov    $0x0,%al
call   10f0 <finish_bucketsort@plt>
mov    $0x0,%al
call   1080 <getBucketTime@plt>
movsd  %xmm0,-0x110(%rbp)
ff
mov    -0x80(%rbp),%rax
mov    %rax,-0x118(%rbp)
mov    -0x70(%rbp),%rax
mov    %rax,-0x120(%rbp)
movl   $0x0,-0x124(%rbp)
movl   $0x0,-0x128(%rbp)
cmpl   $0x400,-0x128(%rbp)
jge    1730 <main+0x510>
mov    -0xe8(%rbp),%rax
movslq -0x128(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
shl    $0x2,%eax
add    -0x124(%rbp),%eax
mov    %eax,-0x124(%rbp)
mov    -0x128(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x128(%rbp)
jmp    16ec <main+0x4cc>
mov    -0x124(%rbp),%edi
call   1090 <init_mergesort@plt>
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x130(%rbp)
mov    -0x124(%rbp),%edi
mov    -0x118(%rbp),%rdx
mov    -0x120(%rbp),%rcx
mov    -0xe8(%rbp),%r8
mov    -0xf0(%rbp),%r9
mov    -0xf8(%rbp),%rax
mov    $0x400,%esi
mov    %rax,(%rsp)
call   1070 <runMergeSort@plt>
mov    %rax,-0x138(%rbp)
mov    $0x0,%al
call   1030 <clock@plt>
sub    -0x130(%rbp),%rax
mov    %rax,-0x140(%rbp)
mov    $0x0,%al
call   1130 <finish_mergesort@plt>
mov    -0x138(%rbp),%rax
mov    %rax,-0x88(%rbp)
xor    %eax,%eax
add    $0x150,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x68,%rsp
mov    %rsi,%r14
mov    0x8(%rsi),%rdi
lea    0xdc4(%rip),%rsi
call   10b0 <strcmp@plt>
test   %rax,%rax
je     12b1 <main+0x81>
mov    0x8(%r14),%rdi
lea    0xdaf(%rip),%rsi
call   1120 <fopen@plt>
test   %rax,%rax
je     160d <main+0x3dd>
mov    %rax,%rbp
mov    $0xffffffff,%r12d
lea    0xd93(%rip),%r15
lea    0x50(%rsp),%r13
mov    0x2d5d(%rip),%rbx
nopl   0x0(%rax,%rax,1)
mov    %rbp,%rdi
mov    %r15,%rsi
mov    %r13,%rdx
call   1070 <fscanf@plt>
add    $0x1,%r12d
cmp    (%rbx),%rax
jne    1290 <main+0x60>
mov    %rbp,%rdi
call   1050 <fclose@plt>
jmp    12b7 <main+0x87>
mov    $0xf4240,%r12d
lea    0xd57(%rip),%rdi
mov    %r12d,%esi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x4000(,%r12,4),%ebp
mov    %ebp,%edi
call   10e0 <malloc@plt>
mov    %rax,%r15
mov    %ebp,%edi
call   10e0 <malloc@plt>
mov    %rax,%rbx
mov    %ebp,%edi
call   10e0 <malloc@plt>
mov    %rax,0x38(%rsp)
mov    %ebp,%edi
call   10e0 <malloc@plt>
mov    0x2cda(%rip),%rax
movss  (%rax),%xmm1
movaps 0xcf7(%rip),%xmm0
movaps %xmm1,0x20(%rsp)
xorps  %xmm1,%xmm0
movaps %xmm0,0x10(%rsp)
mov    0x8(%r14),%rdi
lea    0xcef(%rip),%rsi
call   10b0 <strcmp@plt>
test   %rax,%rax
mov    %r15,0x40(%rsp)
mov    %ebp,0x34(%rsp)
mov    %rbx,0x48(%rsp)
je     13d0 <main+0x1a0>
mov    0x8(%r14),%rdi
lea    0xcc8(%rip),%rsi
call   1120 <fopen@plt>
test   %r12d,%r12d
je     1453 <main+0x223>
mov    %rax,%rbp
mov    %r12d,%r13d
lea    0xcaf(%rip),%r14
movaps 0x20(%rsp),%xmm3
movaps 0x10(%rsp),%xmm0
jmp    13a7 <main+0x177>
nop
movaps 0x20(%rsp),%xmm3
minss  %xmm0,%xmm3
movaps 0x10(%rsp),%xmm4
movaps %xmm0,%xmm2
cmpunordss %xmm0,%xmm2
movaps %xmm2,%xmm1
andps  %xmm4,%xmm1
maxss  %xmm0,%xmm4
andnps %xmm4,%xmm2
orps   %xmm1,%xmm2
add    $0x4,%r15
movaps %xmm2,%xmm0
add    $0xffffffffffffffff,%r13
je     145d <main+0x22d>
movaps %xmm0,0x10(%rsp)
movaps %xmm3,0x20(%rsp)
mov    %rbp,%rdi
mov    %r14,%rsi
mov    %r15,%rdx
call   1070 <fscanf@plt>
movss  (%r15),%xmm0
ucomiss %xmm0,%xmm0
jnp    1370 <main+0x140>
movaps 0x20(%rsp),%xmm3
jmp    1379 <main+0x149>
test   %r12d,%r12d
je     1453 <main+0x223>
mov    %r12d,%r15d
mov    0x2bfd(%rip),%r14
xor    %ebp,%ebp
movaps 0x10(%rsp),%xmm2
jmp    1424 <main+0x1f4>
nopl   0x0(%rax)
movaps 0x10(%rsp),%xmm2
maxss  %xmm3,%xmm2
movaps 0x20(%rsp),%xmm4
movaps %xmm4,%xmm0
minss  %xmm3,%xmm0
cmpunordss %xmm3,%xmm3
movaps %xmm3,%xmm1
andnps %xmm0,%xmm1
andps  %xmm4,%xmm3
orps   %xmm1,%xmm3
add    $0x1,%rbp
movaps %xmm3,0x20(%rsp)
cmp    %rbp,%r15
je     145d <main+0x22d>
movaps %xmm2,0x10(%rsp)
xor    %eax,%eax
call   1150 <rand@plt>
xorps  %xmm3,%xmm3
cvtsi2ss %rax,%xmm3
divss  (%r14),%xmm3
mov    0x40(%rsp),%rax
movss  %xmm3,(%rax,%rbp,4)
ucomiss %xmm3,%xmm3
jnp    13f0 <main+0x1c0>
movaps 0x10(%rsp),%xmm2
jmp    13f9 <main+0x1c9>
movaps 0x20(%rsp),%xmm3
movaps 0x10(%rsp),%xmm2
movaps %xmm3,0x20(%rsp)
movaps %xmm2,0x10(%rsp)
movaps 0xbe2(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movw   $0x74,0x60(%rsp)
lea    0xbb0(%rip),%rsi
lea    0x50(%rsp),%rdi
call   1120 <fopen@plt>
mov    %rax,%rbp
xor    %ebx,%ebx
lea    0xb9c(%rip),%r14
mov    0x40(%rsp),%r15
nopl   0x0(%rax)
movss  (%r15,%rbx,4),%xmm0
mov    %rbp,%rdi
mov    %r14,%rsi
call   10c0 <fprintf@plt>
add    $0x1,%rbx
cmp    $0xf4240,%rbx
jne    14a0 <main+0x270>
mov    %rbp,%rdi
call   1050 <fclose@plt>
mov    0x48(%rsp),%rdi
mov    %r15,%rsi
mov    0x34(%rsp),%edx
call   10d0 <memcpy@plt>
xor    %eax,%eax
call   1040 <clock@plt>
mov    %r12d,%edi
call   10f0 <init_bucketsort@plt>
mov    $0x1000,%edi
call   10e0 <malloc@plt>
mov    %rax,%rbp
mov    $0x1000,%edi
call   10e0 <malloc@plt>
mov    %rax,%r14
mov    $0x1004,%edi
call   10e0 <malloc@plt>
mov    %rax,%r13
xor    %eax,%eax
call   1040 <clock@plt>
mov    %r15,%rdi
mov    0x38(%rsp),%rsi
mov    %r12d,%edx
mov    %rbp,%rcx
mov    %r14,%r8
movdqa 0x20(%rsp),%xmm0
movdqa 0x10(%rsp),%xmm1
mov    %r13,%r9
call   1110 <bucketSort@plt>
xor    %eax,%eax
call   1040 <clock@plt>
xor    %eax,%eax
call   1100 <finish_bucketsort@plt>
xor    %eax,%eax
call   1090 <getBucketTime@plt>
pxor   %xmm0,%xmm0
mov    $0xc,%eax
pxor   %xmm1,%xmm1
nopl   0x0(%rax,%rax,1)
movdqu -0x30(%rbp,%rax,4),%xmm2
movdqu -0x20(%rbp,%rax,4),%xmm3
pslld  $0x2,%xmm2
paddd  %xmm0,%xmm2
movdqu -0x10(%rbp,%rax,4),%xmm0
pslld  $0x2,%xmm3
paddd  %xmm1,%xmm3
movdqu 0x0(%rbp,%rax,4),%xmm1
pslld  $0x2,%xmm0
paddd  %xmm2,%xmm0
pslld  $0x2,%xmm1
paddd  %xmm3,%xmm1
add    $0x10,%rax
cmp    $0x40c,%rax
jne    1560 <main+0x330>
paddd  %xmm0,%xmm1
pshufd $0xee,%xmm1,%xmm0
paddd  %xmm1,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%ebx
mov    %ebx,%edi
call   10a0 <init_mergesort@plt>
xor    %eax,%eax
call   1040 <clock@plt>
mov    %r13,(%rsp)
mov    %ebx,%edi
mov    $0x400,%esi
mov    0x38(%rsp),%rdx
mov    %r15,%rcx
mov    %rbp,%r8
mov    %r14,%r9
call   1080 <runMergeSort@plt>
xor    %eax,%eax
call   1040 <clock@plt>
xor    %eax,%eax
call   1140 <finish_mergesort@plt>
xor    %eax,%eax
add    $0x68,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0xa23(%rip),%rdi
call   1030 <puts@plt>
mov    0x29a8(%rip),%rax
mov    (%rax),%edi
call   1130 <exit@plt>

LLVM IR (-O0):
@.str = [2 x i8] c"r\00"
@.str.1 = [21 x i8] c"Error reading file \0A\00"
@EXIT_FAILURE = global i32 0
@.str.2 = [3 x i8] c"%f\00"
@EOF = global i64 0
@.str.3 = [28 x i8] c"Sorting list of %d floats.\0A\00"
@FLT_MAX = global float 0.000000e+00
@RAND_MAX = global float 0.000000e+00
@__const.main.filename2 = [18 x i8] c"./hybridinput.txt\00"
@.str.4 = [2 x i8] c"w\00"
@.str.5 = [4 x i8] c"%f \00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca i64
%9 = alloca i64
%10 = alloca i32*
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32*
%20 = alloca i32
%21 = alloca float
%22 = alloca i32
%23 = alloca float*
%24 = alloca float*
%25 = alloca float*
%26 = alloca float*
%27 = alloca float
%28 = alloca float
%29 = alloca i32
%30 = alloca i32*
%31 = alloca i32
%32 = alloca i32*
%33 = alloca [18 x i8]
%34 = alloca i32
%35 = alloca i64
%36 = alloca i32*
%37 = alloca i32*
%38 = alloca i32*
%39 = alloca i64
%40 = alloca i64
%41 = alloca double
%42 = alloca i32*
%43 = alloca i32*
%44 = alloca i32
%45 = alloca i32
%46 = alloca i64
%47 = alloca i32*
%48 = alloca i64
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
store i32 0, i32* %18
%49 = load i8**, i8*** %5
%50 = getelementptr inbounds i8*, i8** %49, i64 1
%51 = load i8*, i8** %50
%52 = call i64 @strcmp(i8* %51, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%53 = icmp eq i64 %52, 0
br i1 %53, label %54, label %55
54: ; preds = %2
store i32 1000000, i32* %18
br label %79
55: ; preds = %2
%56 = load i8**, i8*** %5
%57 = getelementptr inbounds i8*, i8** %56, i64 1
%58 = load i8*, i8** %57
%59 = call i32* @fopen(i8* %58, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %59, i32** %19
%60 = load i32*, i32** %19
%61 = icmp eq i32* %60, null
br i1 %61, label %62, label %66
62: ; preds = %55
%63 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0))
%64 = load i32, i32* @EXIT_FAILURE
%65 = call i32 @exit(i32 %64)
unreachable
66: ; preds = %55
store i32 0, i32* %20
br label %67
67: ; preds = %72, %66
%68 = load i32*, i32** %19
%69 = call i64 @fscanf(i32* %68, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float* %21)
%70 = load i64, i64* @EOF
%71 = icmp ne i64 %69, %70
br i1 %71, label %72, label %75
72: ; preds = %67
%73 = load i32, i32* %20
%74 = add nsw i32 %73, 1
store i32 %74, i32* %20
br label %67
75: ; preds = %67
%76 = load i32*, i32** %19
%77 = call i32 @fclose(i32* %76)
%78 = load i32, i32* %20
store i32 %78, i32* %18
br label %79
79: ; preds = %75, %54
%80 = load i32, i32* %18
%81 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.3, i64 0, i64 0), i32 %80)
%82 = load i32, i32* %18
%83 = add nsw i32 %82, 4096
%84 = sext i32 %83 to i64
%85 = mul i64 %84, 4
%86 = trunc i64 %85 to i32
store i32 %86, i32* %22
%87 = load i32, i32* %22
%88 = call i64 @malloc(i32 %87)
%89 = inttoptr i64 %88 to float*
store float* %89, float** %23
%90 = load i32, i32* %22
%91 = call i64 @malloc(i32 %90)
%92 = inttoptr i64 %91 to float*
store float* %92, float** %24
%93 = load i32, i32* %22
%94 = call i64 @malloc(i32 %93)
%95 = inttoptr i64 %94 to float*
store float* %95, float** %25
%96 = load i32, i32* %22
%97 = call i64 @malloc(i32 %96)
%98 = inttoptr i64 %97 to float*
store float* %98, float** %26
%99 = load float, float* @FLT_MAX
store float %99, float* %27
%100 = load float, float* @FLT_MAX
%101 = fneg float %100
store float %101, float* %28
%102 = load i8**, i8*** %5
%103 = getelementptr inbounds i8*, i8** %102, i64 1
%104 = load i8*, i8** %103
%105 = call i64 @strcmp(i8* %104, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%106 = icmp eq i64 %105, 0
br i1 %106, label %107, label %139
107: ; preds = %79
store i32 0, i32* %29
br label %108
108: ; preds = %135, %107
%109 = load i32, i32* %29
%110 = load i32, i32* %18
%111 = icmp slt i32 %109, %110
br i1 %111, label %112, label %138
112: ; preds = %108
%113 = call i64 (...) @rand()
%114 = sitofp i64 %113 to float
%115 = load float, float* @RAND_MAX
%116 = fdiv float %114, %115
%117 = load float*, float** %23
%118 = load i32, i32* %29
%119 = sext i32 %118 to i64
%120 = getelementptr inbounds float, float* %117, i64 %119
store float %116, float* %120
%121 = load float*, float** %23
%122 = load i32, i32* %29
%123 = sext i32 %122 to i64
%124 = getelementptr inbounds float, float* %121, i64 %123
%125 = load float, float* %124
%126 = load float, float* %27
%127 = call float @llvm.minnum.f32(float %125, float %126)
store float %127, float* %27
%128 = load float*, float** %23
%129 = load i32, i32* %29
%130 = sext i32 %129 to i64
%131 = getelementptr inbounds float, float* %128, i64 %130
%132 = load float, float* %131
%133 = load float, float* %28
%134 = call float @llvm.maxnum.f32(float %132, float %133)
store float %134, float* %28
br label %135
135: ; preds = %112
%136 = load i32, i32* %29
%137 = add nsw i32 %136, 1
store i32 %137, i32* %29
br label %108
138: ; preds = %108
br label %173
139: ; preds = %79
%140 = load i8**, i8*** %5
%141 = getelementptr inbounds i8*, i8** %140, i64 1
%142 = load i8*, i8** %141
%143 = call i32* @fopen(i8* %142, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %143, i32** %30
store i32 0, i32* %31
br label %144
144: ; preds = %169, %139
%145 = load i32, i32* %31
%146 = load i32, i32* %18
%147 = icmp slt i32 %145, %146
br i1 %147, label %148, label %172
148: ; preds = %144
%149 = load i32*, i32** %30
%150 = load float*, float** %23
%151 = load i32, i32* %31
%152 = sext i32 %151 to i64
%153 = getelementptr inbounds float, float* %150, i64 %152
%154 = call i64 @fscanf(i32* %149, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float* %153)
%155 = load float*, float** %23
%156 = load i32, i32* %31
%157 = sext i32 %156 to i64
%158 = getelementptr inbounds float, float* %155, i64 %157
%159 = load float, float* %158
%160 = load float, float* %27
%161 = call float @llvm.minnum.f32(float %159, float %160)
store float %161, float* %27
%162 = load float*, float** %23
%163 = load i32, i32* %31
%164 = sext i32 %163 to i64
%165 = getelementptr inbounds float, float* %162, i64 %164
%166 = load float, float* %165
%167 = load float, float* %28
%168 = call float @llvm.maxnum.f32(float %166, float %167)
store float %168, float* %28
br label %169
169: ; preds = %148
%170 = load i32, i32* %31
%171 = add nsw i32 %170, 1
store i32 %171, i32* %31
br label %144
172: ; preds = %144
br label %173
173: ; preds = %172, %138
%174 = bitcast [18 x i8]* %33 to i8*
%175 = getelementptr inbounds [18 x i8], [18 x i8]* %33, i64 0, i64 0
%176 = call i32* @fopen(i8* %175, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i64 0, i64 0))
store i32* %176, i32** %32
store i32 0, i32* %34
br label %177
177: ; preds = %188, %173
%178 = load i32, i32* %34
%179 = icmp slt i32 %178, 1000000
br i1 %179, label %180, label %191
180: ; preds = %177
%181 = load i32*, i32** %32
%182 = load float*, float** %23
%183 = load i32, i32* %34
%184 = sext i32 %183 to i64
%185 = getelementptr inbounds float, float* %182, i64 %184
%186 = load float, float* %185
%187 = call i32 @fprintf(i32* %181, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.5, i64 0, i64 0), float %186)
br label %188
188: ; preds = %180
%189 = load i32, i32* %34
%190 = add nsw i32 %189, 1
store i32 %190, i32* %34
br label %177
191: ; preds = %177
%192 = load i32*, i32** %32
%193 = call i32 @fclose(i32* %192)
%194 = load float*, float** %24
%195 = load float*, float** %23
%196 = load i32, i32* %22
%197 = call i32 @memcpy(float* %194, float* %195, i32 %196)
%198 = call i64 (...) @clock()
store i64 %198, i64* %35
%199 = load i32, i32* %18
%200 = call i32 @init_bucketsort(i32 %199)
%201 = call i64 @malloc(i32 4096)
%202 = inttoptr i64 %201 to i32*
store i32* %202, i32** %36
%203 = call i64 @malloc(i32 4096)
%204 = inttoptr i64 %203 to i32*
store i32* %204, i32** %37
%205 = call i64 @malloc(i32 4100)
%206 = inttoptr i64 %205 to i32*
store i32* %206, i32** %38
%207 = call i64 (...) @clock()
store i64 %207, i64* %39
%208 = load float*, float** %23
%209 = load float*, float** %25
%210 = load i32, i32* %18
%211 = load i32*, i32** %36
%212 = load i32*, i32** %37
%213 = load float, float* %27
%214 = load float, float* %28
%215 = load i32*, i32** %38
%216 = call i32 @bucketSort(float* %208, float* %209, i32 %210, i32* %211, i32* %212, float %213, float %214, i32* %215)
%217 = call i64 (...) @clock()
%218 = load i64, i64* %39
%219 = sub nsw i64 %217, %218
store i64 %219, i64* %40
%220 = call i32 (...) @finish_bucketsort()
%221 = call double (...) @getBucketTime()
store double %221, double* %41
%222 = load float*, float** %25
%223 = bitcast float* %222 to i32*
store i32* %223, i32** %42
%224 = load float*, float** %23
%225 = bitcast float* %224 to i32*
store i32* %225, i32** %43
store i32 0, i32* %44
store i32 0, i32* %45
br label %226
226: ; preds = %238, %191
%227 = load i32, i32* %45
%228 = icmp slt i32 %227, 1024
br i1 %228, label %229, label %241
229: ; preds = %226
%230 = load i32*, i32** %36
%231 = load i32, i32* %45
%232 = sext i32 %231 to i64
%233 = getelementptr inbounds i32, i32* %230, i64 %232
%234 = load i32, i32* %233
%235 = mul nsw i32 %234, 4
%236 = load i32, i32* %44
%237 = add nsw i32 %236, %235
store i32 %237, i32* %44
br label %238
238: ; preds = %229
%239 = load i32, i32* %45
%240 = add nsw i32 %239, 1
store i32 %240, i32* %45
br label %226
241: ; preds = %226
%242 = load i32, i32* %44
%243 = call i32 @init_mergesort(i32 %242)
%244 = call i64 (...) @clock()
store i64 %244, i64* %46
%245 = load i32, i32* %44
%246 = load i32*, i32** %42
%247 = load i32*, i32** %43
%248 = load i32*, i32** %36
%249 = load i32*, i32** %37
%250 = load i32*, i32** %38
%251 = call i32* @runMergeSort(i32 %245, i32 1024, i32* %246, i32* %247, i32* %248, i32* %249, i32* %250)
store i32* %251, i32** %47
%252 = call i64 (...) @clock()
%253 = load i64, i64* %46
%254 = sub nsw i64 %252, %253
store i64 %254, i64* %48
%255 = call i32 (...) @finish_mergesort()
%256 = load i32*, i32** %47
%257 = bitcast i32* %256 to float*
store float* %257, float** %26
ret i32 0
}

LLVM IR (-O2):
@.str = [2 x i8] c"r\00"
@EXIT_FAILURE = global i32 0
@.str.2 = [3 x i8] c"%f\00"
@EOF = global i64 0
@.str.3 = [28 x i8] c"Sorting list of %d floats.\0A\00"
@FLT_MAX = global float 0.000000e+00
@RAND_MAX = global float 0.000000e+00
@__const.main.filename2 = [18 x i8] c"./hybridinput.txt\00"
@.str.4 = [2 x i8] c"w\00"
@.str.5 = [4 x i8] c"%f \00"
@str = [20 x i8] c"Error reading file \00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = alloca float
%4 = alloca [18 x i8]
%5 = getelementptr inbounds i8*, i8** %1, i64 1
%6 = load i8*, i8** %5
%7 = tail call i64 @strcmp(i8* %6, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%8 = icmp eq i64 %7, 0
br i1 %8, label %27, label %9
9: ; preds = %2
%10 = load i8*, i8** %5
%11 = tail call i32* @fopen(i8* %10, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%12 = icmp eq i32* %11, null
br i1 %12, label %13, label %17
13: ; preds = %9
%14 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @str, i64 0, i64 0))
%15 = load i32, i32* @EXIT_FAILURE
%16 = tail call i32 @exit(i32 %15)
unreachable
17: ; preds = %9
%18 = bitcast float* %3 to i8*
br label %19
19: ; preds = %19, %17
%20 = phi i32 [ 0, %17 ], [ %24, %19 ]
%21 = call i64 @fscanf(i32* %11, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float* %3)
%22 = load i64, i64* @EOF
%23 = icmp eq i64 %21, %22
%24 = add nuw nsw i32 %20, 1
br i1 %23, label %25, label %19
25: ; preds = %19
%26 = call i32 @fclose(i32* %11)
br label %27
27: ; preds = %2, %25
%28 = phi i32 [ %20, %25 ], [ 1000000, %2 ]
%29 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([28 x i8], [28 x i8]* @.str.3, i64 0, i64 0), i32 %28)
%30 = shl i32 %28, 2
%31 = add i32 %30, 16384
%32 = call i64 @malloc(i32 %31)
%33 = inttoptr i64 %32 to float*
%34 = call i64 @malloc(i32 %31)
%35 = inttoptr i64 %34 to float*
%36 = call i64 @malloc(i32 %31)
%37 = inttoptr i64 %36 to float*
%38 = call i64 @malloc(i32 %31)
%39 = load float, float* @FLT_MAX
%40 = fneg float %39
%41 = load i8*, i8** %5
%42 = call i64 @strcmp(i8* %41, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%43 = icmp eq i64 %42, 0
br i1 %43, label %44, label %61
44: ; preds = %27
%45 = icmp eq i32 %28, 0
br i1 %45, label %78, label %46
46: ; preds = %44
%47 = zext i32 %28 to i64
br label %48
48: ; preds = %46, %48
%49 = phi i64 [ 0, %46 ], [ %59, %48 ]
%50 = phi float [ %39, %46 ], [ %57, %48 ]
%51 = phi float [ %40, %46 ], [ %58, %48 ]
%52 = call i64 (...) @rand()
%53 = sitofp i64 %52 to float
%54 = load float, float* @RAND_MAX
%55 = fdiv float %53, %54
%56 = getelementptr inbounds float, float* %33, i64 %49
store float %55, float* %56
%57 = call float @llvm.minnum.f32(float %55, float %50)
%58 = call float @llvm.maxnum.f32(float %55, float %51)
%59 = add nuw nsw i64 %49, 1
%60 = icmp eq i64 %59, %47
br i1 %60, label %78, label %48
61: ; preds = %27
%62 = load i8*, i8** %5
%63 = call i32* @fopen(i8* %62, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%64 = icmp eq i32 %28, 0
br i1 %64, label %78, label %65
65: ; preds = %61
%66 = zext i32 %28 to i64
br label %67
67: ; preds = %65, %67
%68 = phi i64 [ 0, %65 ], [ %76, %67 ]
%69 = phi float [ %39, %65 ], [ %74, %67 ]
%70 = phi float [ %40, %65 ], [ %75, %67 ]
%71 = getelementptr inbounds float, float* %33, i64 %68
%72 = call i64 @fscanf(i32* %63, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), float* %71)
%73 = load float, float* %71
%74 = call float @llvm.minnum.f32(float %73, float %69)
%75 = call float @llvm.maxnum.f32(float %73, float %70)
%76 = add nuw nsw i64 %68, 1
%77 = icmp eq i64 %76, %66
br i1 %77, label %78, label %67
78: ; preds = %67, %48, %61, %44
%79 = phi float [ %40, %44 ], [ %40, %61 ], [ %58, %48 ], [ %75, %67 ]
%80 = phi float [ %39, %44 ], [ %39, %61 ], [ %57, %48 ], [ %74, %67 ]
%81 = getelementptr inbounds [18 x i8], [18 x i8]* %4, i64 0, i64 0
%82 = call i32* @fopen(i8* %81, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i64 0, i64 0))
br label %136
83: ; preds = %136
%84 = call i32 @fclose(i32* %82)
%85 = call i32 @memcpy(float* %35, float* %33, i32 %31)
%86 = call i64 (...) @clock()
%87 = call i32 @init_bucketsort(i32 %28)
%88 = call i64 @malloc(i32 4096)
%89 = inttoptr i64 %88 to i32*
%90 = call i64 @malloc(i32 4096)
%91 = inttoptr i64 %90 to i32*
%92 = call i64 @malloc(i32 4100)
%93 = inttoptr i64 %92 to i32*
%94 = call i64 (...) @clock()
%95 = call i32 @bucketSort(float* %33, float* %37, i32 %28, i32* %89, i32* %91, float %80, float %79, i32* %93)
%96 = call i64 (...) @clock()
%97 = call i32 (...) @finish_bucketsort()
%98 = call double (...) @getBucketTime()
br label %99
99: ; preds = %99, %83
%100 = phi i64 [ 0, %83 ], [ %124, %99 ]
%101 = phi <4 x i32> [ zeroinitializer, %83 ], [ %122, %99 ]
%102 = phi <4 x i32> [ zeroinitializer, %83 ], [ %123, %99 ]
%103 = getelementptr inbounds i32, i32* %89, i64 %100
%104 = bitcast i32* %103 to <4 x i32>*
%105 = load <4 x i32>, <4 x i32>* %104
%106 = getelementptr inbounds i32, i32* %103, i64 4
%107 = bitcast i32* %106 to <4 x i32>*
%108 = load <4 x i32>, <4 x i32>* %107
%109 = shl nsw <4 x i32> %105, <i32 2, i32 2, i32 2, i32 2>
%110 = shl nsw <4 x i32> %108, <i32 2, i32 2, i32 2, i32 2>
%111 = add <4 x i32> %109, %101
%112 = add <4 x i32> %110, %102
%113 = or i64 %100, 8
%114 = getelementptr inbounds i32, i32* %89, i64 %113
%115 = bitcast i32* %114 to <4 x i32>*
%116 = load <4 x i32>, <4 x i32>* %115
%117 = getelementptr inbounds i32, i32* %114, i64 4
%118 = bitcast i32* %117 to <4 x i32>*
%119 = load <4 x i32>, <4 x i32>* %118
%120 = shl nsw <4 x i32> %116, <i32 2, i32 2, i32 2, i32 2>
%121 = shl nsw <4 x i32> %119, <i32 2, i32 2, i32 2, i32 2>
%122 = add <4 x i32> %120, %111
%123 = add <4 x i32> %121, %112
%124 = add nuw nsw i64 %100, 16
%125 = icmp eq i64 %124, 1024
br i1 %125, label %126, label %99
126: ; preds = %99
%127 = add <4 x i32> %123, %122
%128 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %127)
%129 = inttoptr i64 %32 to i32*
%130 = inttoptr i64 %36 to i32*
%131 = call i32 @init_mergesort(i32 %128)
%132 = call i64 (...) @clock()
%133 = call i32* @runMergeSort(i32 %128, i32 1024, i32* %130, i32* %129, i32* %89, i32* %91, i32* %93)
%134 = call i64 (...) @clock()
%135 = call i32 (...) @finish_mergesort()
ret i32 0
136: ; preds = %78, %136
%137 = phi i64 [ 0, %78 ], [ %141, %136 ]
%138 = getelementptr inbounds float, float* %33, i64 %137
%139 = load float, float* %138
%140 = call i32 @fprintf(i32* %82, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.5, i64 0, i64 0), float %139)
%141 = add nuw nsw i64 %137, 1
%142 = icmp eq i64 %141, 1000000
br i1 %142, label %83, label %136
}