void QuickSortDouble(double *a, int *b, int n) {
  if (n < 2)
    return;
  double p = a[n / 2];
  double *l = a;
  int *ll = b;
  double *r = a + n - 1;
  int *rr = b + n - 1;
  while (l <= r) {
    if (*l < p) {
      l++;
      ll++;
    } else if (*r > p) {
      r--;
      rr--;
    } else {
      double t = *l;
      double tt = *ll;
      *l = *r;
      *ll = *rr;
      *r = t;
      *rr = tt;
      l++;
      ll++;
      r--;
      rr--;
    }
  }
  QuickSortDouble(a, b, r - a + 1);
  QuickSortDouble(l, ll, a + n - l);
}


x86 assembly (clang, -O0):
<QuickSortDouble>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
cmpl   $0x2,-0x14(%rbp)
jge    1132 <QuickSortDouble+0x22>
jmp    12db <QuickSortDouble+0x1cb>
mov    -0x8(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x58(%rbp),%rax
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x38(%rbp),%rax
ja     1290 <QuickSortDouble+0x180>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm1
movsd  -0x20(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11d8 <QuickSortDouble+0xc8>
mov    -0x28(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
jmp    128b <QuickSortDouble+0x17b>
mov    -0x38(%rbp),%rax
movsd  (%rax),%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    1208 <QuickSortDouble+0xf8>
mov    -0x38(%rbp),%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x40(%rbp)
jmp    1286 <QuickSortDouble+0x176>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x30(%rbp),%rax
cvtsi2sdl (%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x38(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x40(%rbp),%rax
mov    (%rax),%ecx
mov    -0x30(%rbp),%rax
mov    %ecx,(%rax)
movsd  -0x48(%rbp),%xmm0
mov    -0x38(%rbp),%rax
movsd  %xmm0,(%rax)
cvttsd2si -0x50(%rbp),%ecx
mov    -0x40(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x28(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
mov    -0x38(%rbp),%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x38(%rbp)
mov    -0x40(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x40(%rbp)
jmp    128b <QuickSortDouble+0x17b>
jmp    1196 <QuickSortDouble+0x86>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x38(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
sar    $0x3,%rax
add    $0x1,%rax
mov    %eax,%edx
call   1030 <QuickSortDouble@plt>
mov    -0x28(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x28(%rbp),%rcx
sub    %rcx,%rax
sar    $0x3,%rax
mov    %eax,%edx
call   1030 <QuickSortDouble@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<QuickSortDouble>:
push   %r15
push   %r14
push   %rbx
cmp    $0x2,%edx
jge    1120 <QuickSortDouble+0x10>
pop    %rbx
pop    %r14
pop    %r15
ret
mov    %edx,%r14d
jmp    115c <QuickSortDouble+0x4c>
cs nopw 0x0(%rax,%rax,1)
nop
mov    %rsi,%r15
mov    %rdi,%rbx
lea    (%rdi,%r8,8),%r14
sub    %rdi,%rdx
shr    $0x3,%rdx
add    $0x1,%edx
call   1030 <QuickSortDouble@plt>
sub    %rbx,%r14
shr    $0x3,%r14
mov    %r15,%rsi
mov    %rbx,%rdi
cmp    $0x1,%r14d
jle    111a <QuickSortDouble+0xa>
mov    %r14d,%r8d
lea    (%rdi,%r8,8),%rdx
add    $0xfffffffffffffff8,%rdx
cmp    %rdx,%rdi
ja     1130 <QuickSortDouble+0x20>
shr    %r14d
movsd  (%rdi,%r14,8),%xmm0
lea    (%rsi,%r8,4),%r9
add    $0xfffffffffffffffc,%r9
mov    %rdi,%rbx
mov    %rsi,%r15
jmp    119d <QuickSortDouble+0x8d>
cs nopw 0x0(%rax,%rax,1)
nop
add    $0x8,%rbx
add    $0x4,%r15
cmp    %rdx,%rbx
ja     1136 <QuickSortDouble+0x26>
movsd  (%rbx),%xmm1
ucomisd %xmm1,%xmm0
ja     1190 <QuickSortDouble+0x80>
movsd  (%rdx),%xmm2
ucomisd %xmm0,%xmm2
ja     11cd <QuickSortDouble+0xbd>
mov    (%r15),%eax
movsd  %xmm2,(%rbx)
mov    (%r9),%ecx
mov    %ecx,(%r15)
movsd  %xmm1,(%rdx)
mov    %eax,(%r9)
add    $0x8,%rbx
add    $0x4,%r15
add    $0xfffffffffffffff8,%rdx
add    $0xfffffffffffffffc,%r9
cmp    %rdx,%rbx
jbe    119d <QuickSortDouble+0x8d>
jmp    1136 <QuickSortDouble+0x26>

LLVM IR (-O0):
define void @QuickSortDouble(double* %0, i32* %1, i32 %2) {
%4 = alloca double*
%5 = alloca i32*
%6 = alloca i32
%7 = alloca double
%8 = alloca double*
%9 = alloca i32*
%10 = alloca double*
%11 = alloca i32*
%12 = alloca double
%13 = alloca double
store double* %0, double** %4
store i32* %1, i32** %5
store i32 %2, i32* %6
%14 = load i32, i32* %6
%15 = icmp slt i32 %14, 2
br i1 %15, label %16, label %17
16: ; preds = %3
br label %110
17: ; preds = %3
%18 = load double*, double** %4
%19 = load i32, i32* %6
%20 = sdiv i32 %19, 2
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds double, double* %18, i64 %21
%23 = load double, double* %22
store double %23, double* %7
%24 = load double*, double** %4
store double* %24, double** %8
%25 = load i32*, i32** %5
store i32* %25, i32** %9
%26 = load double*, double** %4
%27 = load i32, i32* %6
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds double, double* %26, i64 %28
%30 = getelementptr inbounds double, double* %29, i64 -1
store double* %30, double** %10
%31 = load i32*, i32** %5
%32 = load i32, i32* %6
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds i32, i32* %31, i64 %33
%35 = getelementptr inbounds i32, i32* %34, i64 -1
store i32* %35, i32** %11
br label %36
36: ; preds = %86, %17
%37 = load double*, double** %8
%38 = load double*, double** %10
%39 = icmp ule double* %37, %38
br i1 %39, label %40, label %87
40: ; preds = %36
%41 = load double*, double** %8
%42 = load double, double* %41
%43 = load double, double* %7
%44 = fcmp olt double %42, %43
br i1 %44, label %45, label %50
45: ; preds = %40
%46 = load double*, double** %8
%47 = getelementptr inbounds double, double* %46, i32 1
store double* %47, double** %8
%48 = load i32*, i32** %9
%49 = getelementptr inbounds i32, i32* %48, i32 1
store i32* %49, i32** %9
br label %86
50: ; preds = %40
%51 = load double*, double** %10
%52 = load double, double* %51
%53 = load double, double* %7
%54 = fcmp ogt double %52, %53
br i1 %54, label %55, label %60
55: ; preds = %50
%56 = load double*, double** %10
%57 = getelementptr inbounds double, double* %56, i32 -1
store double* %57, double** %10
%58 = load i32*, i32** %11
%59 = getelementptr inbounds i32, i32* %58, i32 -1
store i32* %59, i32** %11
br label %85
60: ; preds = %50
%61 = load double*, double** %8
%62 = load double, double* %61
store double %62, double* %12
%63 = load i32*, i32** %9
%64 = load i32, i32* %63
%65 = sitofp i32 %64 to double
store double %65, double* %13
%66 = load double*, double** %10
%67 = load double, double* %66
%68 = load double*, double** %8
store double %67, double* %68
%69 = load i32*, i32** %11
%70 = load i32, i32* %69
%71 = load i32*, i32** %9
store i32 %70, i32* %71
%72 = load double, double* %12
%73 = load double*, double** %10
store double %72, double* %73
%74 = load double, double* %13
%75 = fptosi double %74 to i32
%76 = load i32*, i32** %11
store i32 %75, i32* %76
%77 = load double*, double** %8
%78 = getelementptr inbounds double, double* %77, i32 1
store double* %78, double** %8
%79 = load i32*, i32** %9
%80 = getelementptr inbounds i32, i32* %79, i32 1
store i32* %80, i32** %9
%81 = load double*, double** %10
%82 = getelementptr inbounds double, double* %81, i32 -1
store double* %82, double** %10
%83 = load i32*, i32** %11
%84 = getelementptr inbounds i32, i32* %83, i32 -1
store i32* %84, i32** %11
br label %85
85: ; preds = %60, %55
br label %86
86: ; preds = %85, %45
br label %36
87: ; preds = %36
%88 = load double*, double** %4
%89 = load i32*, i32** %5
%90 = load double*, double** %10
%91 = load double*, double** %4
%92 = ptrtoint double* %90 to i64
%93 = ptrtoint double* %91 to i64
%94 = sub i64 %92, %93
%95 = sdiv exact i64 %94, 8
%96 = add nsw i64 %95, 1
%97 = trunc i64 %96 to i32
%98 = load double*, double** %8
%99 = load i32*, i32** %9
%100 = load double*, double** %4
%101 = load i32, i32* %6
%102 = sext i32 %101 to i64
%103 = getelementptr inbounds double, double* %100, i64 %102
%104 = load double*, double** %8
%105 = ptrtoint double* %103 to i64
%106 = ptrtoint double* %104 to i64
%107 = sub i64 %105, %106
%108 = sdiv exact i64 %107, 8
%109 = trunc i64 %108 to i32
br label %110
110: ; preds = %87, %16
ret void
}

LLVM IR (-O2):
define void @QuickSortDouble(double* %0, i32* %1, i32 %2) {
%4 = icmp slt i32 %2, 2
br i1 %4, label %65, label %5
5: ; preds = %3, %49
%6 = phi i32 [ %63, %49 ], [ %2, %3 ]
%7 = phi i32* [ %51, %49 ], [ %1, %3 ]
%8 = phi double* [ %52, %49 ], [ %0, %3 ]
%9 = lshr i32 %6, 1
%10 = zext i32 %9 to i64
%11 = getelementptr inbounds double, double* %8, i64 %10
%12 = load double, double* %11
%13 = zext i32 %6 to i64
%14 = getelementptr inbounds double, double* %8, i64 %13
%15 = getelementptr inbounds double, double* %14, i64 -1
%16 = icmp ugt double* %8, %15
br i1 %16, label %49, label %17
17: ; preds = %5
%18 = getelementptr inbounds i32, i32* %7, i64 -1
%19 = getelementptr inbounds i32, i32* %18, i64 %13
br label %20
20: ; preds = %17, %43
%21 = phi double* [ %47, %43 ], [ %8, %17 ]
%22 = phi i32* [ %46, %43 ], [ %7, %17 ]
%23 = phi i32* [ %45, %43 ], [ %19, %17 ]
%24 = phi double* [ %44, %43 ], [ %15, %17 ]
%25 = load double, double* %21
%26 = fcmp olt double %25, %12
br i1 %26, label %27, label %30
27: ; preds = %20
%28 = getelementptr inbounds double, double* %21, i64 1
%29 = getelementptr inbounds i32, i32* %22, i64 1
br label %43
30: ; preds = %20
%31 = load double, double* %24
%32 = fcmp ogt double %31, %12
br i1 %32, label %33, label %36
33: ; preds = %30
%34 = getelementptr inbounds double, double* %24, i64 -1
%35 = getelementptr inbounds i32, i32* %23, i64 -1
br label %43
36: ; preds = %30
%37 = load i32, i32* %22
store double %31, double* %21
%38 = load i32, i32* %23
store i32 %38, i32* %22
store double %25, double* %24
store i32 %37, i32* %23
%39 = getelementptr inbounds double, double* %21, i64 1
%40 = getelementptr inbounds i32, i32* %22, i64 1
%41 = getelementptr inbounds double, double* %24, i64 -1
%42 = getelementptr inbounds i32, i32* %23, i64 -1
br label %43
43: ; preds = %33, %36, %27
%44 = phi double* [ %24, %27 ], [ %34, %33 ], [ %41, %36 ]
%45 = phi i32* [ %23, %27 ], [ %35, %33 ], [ %42, %36 ]
%46 = phi i32* [ %29, %27 ], [ %22, %33 ], [ %40, %36 ]
%47 = phi double* [ %28, %27 ], [ %21, %33 ], [ %39, %36 ]
%48 = icmp ugt double* %47, %44
br i1 %48, label %49, label %20
49: ; preds = %43, %5
%50 = phi double* [ %15, %5 ], [ %44, %43 ]
%51 = phi i32* [ %7, %5 ], [ %46, %43 ]
%52 = phi double* [ %8, %5 ], [ %47, %43 ]
%53 = ptrtoint double* %50 to i64
%54 = ptrtoint double* %8 to i64
%55 = sub i64 %53, %54
%56 = lshr exact i64 %55, 3
%57 = trunc i64 %56 to i32
%58 = add i32 %57, 1
tail call void @QuickSortDouble(double* %8, i32* %7, i32 %58)
%59 = ptrtoint double* %14 to i64
%60 = ptrtoint double* %52 to i64
%61 = sub i64 %59, %60
%62 = lshr exact i64 %61, 3
%63 = trunc i64 %62 to i32
%64 = icmp slt i32 %63, 2
br i1 %64, label %65, label %5
65: ; preds = %49, %3
ret void
}