#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 */
void *alloca(size_t const);
int /*<<< orphan*/ memcpy(void *, void *, size_t const);
int /*<<< orphan*/ pthread_qsort_swap(void *, size_t const, size_t const,
                                      size_t const);
void pthread_qsort_split(void *base, const size_t width, const size_t first,
                         const size_t last, size_t *middle,
                         int (*compare)(const void *, const void *)) {
  short done;
  size_t ii, jj, temp_middle;
  void *test_temp;
  test_temp = alloca(width);
  temp_middle = (first + last) / 2;
  if (compare((void *)((size_t)base + (temp_middle * width)),
              (void *)((size_t)base + (first * width))) < 0) {
    pthread_qsort_swap(base, width, temp_middle, first);
  }
  if (compare((void *)((size_t)base + (last * width)),
              (void *)((size_t)base + (first * width))) < 0) {
    pthread_qsort_swap(base, width, last, first);
  }
  if (compare((void *)((size_t)base + (last * width)),
              (void *)((size_t)base + (temp_middle * width))) < 0) {
    pthread_qsort_swap(base, width, last, temp_middle);
  }
  (void)memcpy(test_temp, (void *)((size_t)base + (temp_middle * width)),
               width);
  pthread_qsort_swap(base, width, temp_middle, (last - 1));
  ii = first;
  jj = last - 1;
  done = 0;
  while (done == 0) {
    ii++;
    while (compare((void *)((size_t)base + (ii * width)), test_temp) < 0) {
      ii++;
    }
    jj--;
    while (compare((void *)((size_t)base + (jj * width)), test_temp) > 0) {
      jj--;
    }
    if (ii < jj) {
      pthread_qsort_swap(base, width, ii, jj);
    } else {
      done = 1;
    }
  }
  pthread_qsort_swap(base, width, ii, (last - 1));
  (*middle) = ii;
  return;
}


x86 assembly (clang, -O0):
<pthread_qsort_split>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x10(%rbp),%rcx
add    $0xf,%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rax
sub    %rcx,%rax
mov    %rax,%rsp
mov    %rax,-0x58(%rbp)
mov    -0x18(%rbp),%rax
add    -0x20(%rbp),%rax
shr    $0x1,%rax
mov    %rax,-0x50(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rdi
mov    -0x50(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rdi
mov    -0x8(%rbp),%rsi
mov    -0x18(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rsi
call   *%rax
cmp    $0x0,%eax
jge    11ad <pthread_qsort_split+0x8d>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x50(%rbp),%rdx
mov    -0x18(%rbp),%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rdi
mov    -0x20(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rdi
mov    -0x8(%rbp),%rsi
mov    -0x18(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rsi
call   *%rax
cmp    $0x0,%eax
jge    11f1 <pthread_qsort_split+0xd1>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x18(%rbp),%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rdi
mov    -0x20(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rdi
mov    -0x8(%rbp),%rsi
mov    -0x50(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rsi
call   *%rax
cmp    $0x0,%eax
jge    1235 <pthread_qsort_split+0x115>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x50(%rbp),%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x58(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    -0x50(%rbp),%rax
imul   -0x10(%rbp),%rax
add    %rax,%rsi
mov    -0x10(%rbp),%rdx
call   1040 <memcpy@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x50(%rbp),%rdx
mov    -0x20(%rbp),%rcx
sub    $0x1,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x18(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rax
sub    $0x1,%rax
mov    %rax,-0x48(%rbp)
movw   $0x0,-0x32(%rbp)
movswl -0x32(%rbp),%eax
cmp    $0x0,%eax
jne    1345 <pthread_qsort_split+0x225>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rdi
mov    -0x40(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rdi
mov    -0x58(%rbp),%rsi
call   *%rax
cmp    $0x0,%eax
jge    12d2 <pthread_qsort_split+0x1b2>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    129e <pthread_qsort_split+0x17e>
mov    -0x48(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x48(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x8(%rbp),%rdi
mov    -0x48(%rbp),%rcx
imul   -0x10(%rbp),%rcx
add    %rcx,%rdi
mov    -0x58(%rbp),%rsi
call   *%rax
cmp    $0x0,%eax
jle    1312 <pthread_qsort_split+0x1f2>
mov    -0x48(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x48(%rbp)
jmp    12de <pthread_qsort_split+0x1be>
mov    -0x40(%rbp),%rax
cmp    -0x48(%rbp),%rax
jae    133a <pthread_qsort_split+0x21a>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x40(%rbp),%rdx
mov    -0x48(%rbp),%rcx
call   1030 <pthread_qsort_swap@plt>
jmp    1340 <pthread_qsort_split+0x220>
movw   $0x1,-0x32(%rbp)
jmp    1285 <pthread_qsort_split+0x165>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x40(%rbp),%rdx
mov    -0x20(%rbp),%rcx
sub    $0x1,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x40(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pthread_qsort_split>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    %r8,-0x60(%rbp)
mov    %rcx,%r15
mov    %rdx,%r13
mov    %rsi,%r12
mov    %rdi,%rdx
mov    %rsp,%rcx
lea    0xf(%rsi),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%rcx
mov    %rcx,-0x50(%rbp)
mov    %rcx,%rsp
lea    (%r15,%r13,1),%rbx
shr    %rbx
mov    %rbx,%rdi
imul   %rsi,%rdi
add    %rdx,%rdi
mov    %r13,%r14
imul   %rsi,%r14
mov    %rdx,-0x30(%rbp)
add    %rdx,%r14
mov    %rdi,-0x58(%rbp)
mov    %r14,%rsi
mov    %r9,-0x48(%rbp)
call   *%r9
test   %eax,%eax
jns    1199 <pthread_qsort_split+0x79>
mov    -0x30(%rbp),%rdi
mov    %r12,%rsi
mov    %rbx,%rdx
mov    %r13,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    %rbx,-0x40(%rbp)
mov    %r15,%rbx
mov    %r12,-0x38(%rbp)
imul   %r12,%rbx
add    -0x30(%rbp),%rbx
mov    %rbx,%rdi
mov    %r14,%rsi
call   *-0x48(%rbp)
test   %eax,%eax
mov    %r15,%r12
jns    11cf <pthread_qsort_split+0xaf>
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    %r12,%rdx
mov    %r13,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    %rbx,%rdi
mov    -0x58(%rbp),%r14
mov    %r14,%rsi
mov    -0x48(%rbp),%rbx
call   *%rbx
test   %eax,%eax
mov    -0x40(%rbp),%r15
jns    11fa <pthread_qsort_split+0xda>
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    %r12,%rdx
mov    %r15,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x50(%rbp),%rdi
mov    %r14,%rsi
mov    -0x38(%rbp),%r15
mov    %r15,%rdx
call   1040 <memcpy@plt>
add    $0xffffffffffffffff,%r12
mov    -0x30(%rbp),%r14
mov    %r14,%rdi
mov    %r15,%rsi
mov    -0x40(%rbp),%rdx
mov    %r12,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    %r12,-0x40(%rbp)
mov    %r14,%rax
mov    %r12,%r14
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    0x1(%r13),%r12
imul   %r15,%r12
add    %rax,%r12
mov    -0x50(%rbp),%r15
nop
add    $0x1,%r13
mov    %r12,%rdi
mov    %r15,%rsi
call   *%rbx
mov    -0x38(%rbp),%rcx
add    %rcx,%r12
test   %eax,%eax
js     1250 <pthread_qsort_split+0x130>
mov    %rbx,%r12
lea    -0x1(%r14),%rbx
imul   %rcx,%rbx
add    -0x30(%rbp),%rbx
cs nopw 0x0(%rax,%rax,1)
add    $0xffffffffffffffff,%r14
mov    %rbx,%rdi
mov    %r15,%rsi
call   *%r12
mov    -0x38(%rbp),%rsi
sub    %rsi,%rbx
test   %eax,%eax
jg     1280 <pthread_qsort_split+0x160>
cmp    %r14,%r13
jae    12ba <pthread_qsort_split+0x19a>
mov    -0x30(%rbp),%rbx
mov    %rbx,%rdi
mov    %rsi,%r15
mov    %r13,%rdx
mov    %r14,%rcx
call   1030 <pthread_qsort_swap@plt>
mov    %rbx,%rax
mov    %r12,%rbx
jmp    1240 <pthread_qsort_split+0x120>
mov    -0x30(%rbp),%rdi
mov    %r13,%rdx
mov    -0x40(%rbp),%rcx
call   1030 <pthread_qsort_swap@plt>
mov    -0x60(%rbp),%rax
mov    %r13,(%rax)
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @pthread_qsort_split(i8* %0, i64 %1, i64 %2, i64 %3, i64* %4, i32 (i8*, i8*)* %5) {
%7 = alloca i8*
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64*
%12 = alloca i32 (i8*, i8*)*
%13 = alloca i16
%14 = alloca i64
%15 = alloca i64
%16 = alloca i64
%17 = alloca i8*
store i8* %0, i8** %7
store i64 %1, i64* %8
store i64 %2, i64* %9
store i64 %3, i64* %10
store i64* %4, i64** %11
store i32 (i8*, i8*)* %5, i32 (i8*, i8*)** %12
%18 = load i64, i64* %8
%19 = alloca i8, i64 %18
store i8* %19, i8** %17
%20 = load i64, i64* %9
%21 = load i64, i64* %10
%22 = add i64 %20, %21
%23 = udiv i64 %22, 2
store i64 %23, i64* %16
%24 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %12
%25 = load i8*, i8** %7
%26 = ptrtoint i8* %25 to i64
%27 = load i64, i64* %16
%28 = load i64, i64* %8
%29 = mul i64 %27, %28
%30 = add i64 %26, %29
%31 = inttoptr i64 %30 to i8*
%32 = load i8*, i8** %7
%33 = ptrtoint i8* %32 to i64
%34 = load i64, i64* %9
%35 = load i64, i64* %8
%36 = mul i64 %34, %35
%37 = add i64 %33, %36
%38 = inttoptr i64 %37 to i8*
%39 = call i32 %24(i8* %31, i8* %38)
%40 = icmp slt i32 %39, 0
br i1 %40, label %41, label %47
41: ; preds = %6
%42 = load i8*, i8** %7
%43 = load i64, i64* %8
%44 = load i64, i64* %16
%45 = load i64, i64* %9
%46 = call i32 @pthread_qsort_swap(i8* %42, i64 %43, i64 %44, i64 %45)
br label %47
47: ; preds = %41, %6
%48 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %12
%49 = load i8*, i8** %7
%50 = ptrtoint i8* %49 to i64
%51 = load i64, i64* %10
%52 = load i64, i64* %8
%53 = mul i64 %51, %52
%54 = add i64 %50, %53
%55 = inttoptr i64 %54 to i8*
%56 = load i8*, i8** %7
%57 = ptrtoint i8* %56 to i64
%58 = load i64, i64* %9
%59 = load i64, i64* %8
%60 = mul i64 %58, %59
%61 = add i64 %57, %60
%62 = inttoptr i64 %61 to i8*
%63 = call i32 %48(i8* %55, i8* %62)
%64 = icmp slt i32 %63, 0
br i1 %64, label %65, label %71
65: ; preds = %47
%66 = load i8*, i8** %7
%67 = load i64, i64* %8
%68 = load i64, i64* %10
%69 = load i64, i64* %9
%70 = call i32 @pthread_qsort_swap(i8* %66, i64 %67, i64 %68, i64 %69)
br label %71
71: ; preds = %65, %47
%72 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %12
%73 = load i8*, i8** %7
%74 = ptrtoint i8* %73 to i64
%75 = load i64, i64* %10
%76 = load i64, i64* %8
%77 = mul i64 %75, %76
%78 = add i64 %74, %77
%79 = inttoptr i64 %78 to i8*
%80 = load i8*, i8** %7
%81 = ptrtoint i8* %80 to i64
%82 = load i64, i64* %16
%83 = load i64, i64* %8
%84 = mul i64 %82, %83
%85 = add i64 %81, %84
%86 = inttoptr i64 %85 to i8*
%87 = call i32 %72(i8* %79, i8* %86)
%88 = icmp slt i32 %87, 0
br i1 %88, label %89, label %95
89: ; preds = %71
%90 = load i8*, i8** %7
%91 = load i64, i64* %8
%92 = load i64, i64* %10
%93 = load i64, i64* %16
%94 = call i32 @pthread_qsort_swap(i8* %90, i64 %91, i64 %92, i64 %93)
br label %95
95: ; preds = %89, %71
%96 = load i8*, i8** %17
%97 = load i8*, i8** %7
%98 = ptrtoint i8* %97 to i64
%99 = load i64, i64* %16
%100 = load i64, i64* %8
%101 = mul i64 %99, %100
%102 = add i64 %98, %101
%103 = inttoptr i64 %102 to i8*
%104 = load i64, i64* %8
%105 = call i32 @memcpy(i8* %96, i8* %103, i64 %104)
%106 = load i8*, i8** %7
%107 = load i64, i64* %8
%108 = load i64, i64* %16
%109 = load i64, i64* %10
%110 = sub i64 %109, 1
%111 = call i32 @pthread_qsort_swap(i8* %106, i64 %107, i64 %108, i64 %110)
%112 = load i64, i64* %9
store i64 %112, i64* %14
%113 = load i64, i64* %10
%114 = sub i64 %113, 1
store i64 %114, i64* %15
store i16 0, i16* %13
br label %115
115: ; preds = %166, %95
%116 = load i16, i16* %13
%117 = sext i16 %116 to i32
%118 = icmp eq i32 %117, 0
br i1 %118, label %119, label %167
119: ; preds = %115
%120 = load i64, i64* %14
%121 = add i64 %120, 1
store i64 %121, i64* %14
br label %122
122: ; preds = %134, %119
%123 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %12
%124 = load i8*, i8** %7
%125 = ptrtoint i8* %124 to i64
%126 = load i64, i64* %14
%127 = load i64, i64* %8
%128 = mul i64 %126, %127
%129 = add i64 %125, %128
%130 = inttoptr i64 %129 to i8*
%131 = load i8*, i8** %17
%132 = call i32 %123(i8* %130, i8* %131)
%133 = icmp slt i32 %132, 0
br i1 %133, label %134, label %137
134: ; preds = %122
%135 = load i64, i64* %14
%136 = add i64 %135, 1
store i64 %136, i64* %14
br label %122
137: ; preds = %122
%138 = load i64, i64* %15
%139 = add i64 %138, -1
store i64 %139, i64* %15
br label %140
140: ; preds = %152, %137
%141 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %12
%142 = load i8*, i8** %7
%143 = ptrtoint i8* %142 to i64
%144 = load i64, i64* %15
%145 = load i64, i64* %8
%146 = mul i64 %144, %145
%147 = add i64 %143, %146
%148 = inttoptr i64 %147 to i8*
%149 = load i8*, i8** %17
%150 = call i32 %141(i8* %148, i8* %149)
%151 = icmp sgt i32 %150, 0
br i1 %151, label %152, label %155
152: ; preds = %140
%153 = load i64, i64* %15
%154 = add i64 %153, -1
store i64 %154, i64* %15
br label %140
155: ; preds = %140
%156 = load i64, i64* %14
%157 = load i64, i64* %15
%158 = icmp ult i64 %156, %157
br i1 %158, label %159, label %165
159: ; preds = %155
%160 = load i8*, i8** %7
%161 = load i64, i64* %8
%162 = load i64, i64* %14
%163 = load i64, i64* %15
%164 = call i32 @pthread_qsort_swap(i8* %160, i64 %161, i64 %162, i64 %163)
br label %166
165: ; preds = %155
store i16 1, i16* %13
br label %166
166: ; preds = %165, %159
br label %115
167: ; preds = %115
%168 = load i8*, i8** %7
%169 = load i64, i64* %8
%170 = load i64, i64* %14
%171 = load i64, i64* %10
%172 = sub i64 %171, 1
%173 = call i32 @pthread_qsort_swap(i8* %168, i64 %169, i64 %170, i64 %172)
%174 = load i64, i64* %14
%175 = load i64*, i64** %11
store i64 %174, i64* %175
ret void
}

LLVM IR (-O2):
define void @pthread_qsort_split(i8* %0, i64 %1, i64 %2, i64 %3, i64* nocapture writeonly %4, i32 (i8*, i8*)* nocapture %5) {
%7 = alloca i8, i64 %1
%8 = add i64 %3, %2
%9 = lshr i64 %8, 1
%10 = ptrtoint i8* %0 to i64
%11 = mul i64 %9, %1
%12 = add i64 %11, %10
%13 = inttoptr i64 %12 to i8*
%14 = mul i64 %2, %1
%15 = add i64 %14, %10
%16 = inttoptr i64 %15 to i8*
%17 = tail call i32 %5(i8* %13, i8* %16)
%18 = icmp slt i32 %17, 0
br i1 %18, label %19, label %21
19: ; preds = %6
%20 = tail call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %9, i64 %2)
br label %21
21: ; preds = %19, %6
%22 = mul i64 %3, %1
%23 = add i64 %22, %10
%24 = inttoptr i64 %23 to i8*
%25 = tail call i32 %5(i8* %24, i8* %16)
%26 = icmp slt i32 %25, 0
br i1 %26, label %27, label %29
27: ; preds = %21
%28 = tail call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %3, i64 %2)
br label %29
29: ; preds = %27, %21
%30 = tail call i32 %5(i8* %24, i8* %13)
%31 = icmp slt i32 %30, 0
br i1 %31, label %32, label %34
32: ; preds = %29
%33 = tail call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %3, i64 %9)
br label %34
34: ; preds = %32, %29
%35 = call i32 @memcpy(i8* %7, i8* %13, i64 %1)
%36 = add i64 %3, -1
%37 = call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %9, i64 %36)
br label %38
38: ; preds = %59, %34
%39 = phi i64 [ %2, %34 ], [ %43, %59 ]
%40 = phi i64 [ %36, %34 ], [ %51, %59 ]
br label %41
41: ; preds = %38, %41
%42 = phi i64 [ %43, %41 ], [ %39, %38 ]
%43 = add i64 %42, 1
%44 = mul i64 %43, %1
%45 = add i64 %44, %10
%46 = inttoptr i64 %45 to i8*
%47 = call i32 %5(i8* %46, i8* %7)
%48 = icmp slt i32 %47, 0
br i1 %48, label %41, label %49
49: ; preds = %41, %49
%50 = phi i64 [ %51, %49 ], [ %40, %41 ]
%51 = add i64 %50, -1
%52 = mul i64 %51, %1
%53 = add i64 %52, %10
%54 = inttoptr i64 %53 to i8*
%55 = call i32 %5(i8* %54, i8* %7)
%56 = icmp sgt i32 %55, 0
br i1 %56, label %49, label %57
57: ; preds = %49
%58 = icmp ult i64 %43, %51
br i1 %58, label %59, label %61
59: ; preds = %57
%60 = call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %43, i64 %51)
br label %38
61: ; preds = %57
%62 = call i32 @pthread_qsort_swap(i8* %0, i64 %1, i64 %43, i64 %36)
store i64 %43, i64* %4
ret void
}