double dqselect(int n, double A[], int k) {
  register int i, j, p;
  register double val;
  k = ((k) > (0) ? (k) : (0));
  k = ((k) < (n - 1) ? (k) : (n - 1));
  while (n > 1) {
    i = 0;
    j = n - 1;
    p = j;
    val = A[p];
    while (i < j) {
      for (; A[i] >= val && i < p; i++)
        ;
      if (A[i] < val) {
        A[p] = A[i];
        p = i;
      }
      for (; A[j] <= val && j > p; j--)
        ;
      if (A[j] > val) {
        A[p] = A[j];
        p = j;
      }
    }
    A[p] = val;
    if (p == k)
      return val;
    else if (p > k)
      n = p;
    else {
      p++;
      n -= p;
      A += p;
      k -= p;
    }
  }
  return A[0];
}


x86 assembly (clang, -O0):
<dqselect>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jle    1123 <dqselect+0x23>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x34(%rbp)
jmp    112d <dqselect+0x2d>
xor    %eax,%eax
mov    %eax,-0x34(%rbp)
jmp    112d <dqselect+0x2d>
mov    -0x34(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    114f <dqselect+0x4f>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x38(%rbp)
jmp    1158 <dqselect+0x58>
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x1,-0xc(%rbp)
jle    133d <dqselect+0x23d>
movl   $0x0,-0x20(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    12bb <dqselect+0x1bb>
jmp    11a1 <dqselect+0xa1>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
xor    %eax,%eax
ucomisd -0x30(%rbp),%xmm0
mov    %al,-0x39(%rbp)
jb     11ca <dqselect+0xca>
mov    -0x20(%rbp),%eax
cmp    -0x28(%rbp),%eax
setl   %al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    11da <dqselect+0xda>
jmp    11ed <dqselect+0xed>
jmp    11df <dqselect+0xdf>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    11a1 <dqselect+0xa1>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x30(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1229 <dqselect+0x129>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
mov    %eax,-0x28(%rbp)
jmp    122e <dqselect+0x12e>
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x30(%rbp),%xmm0
xor    %eax,%eax
ucomisd %xmm1,%xmm0
mov    %al,-0x3a(%rbp)
jb     125b <dqselect+0x15b>
mov    -0x24(%rbp),%eax
cmp    -0x28(%rbp),%eax
setg   %al
mov    %al,-0x3a(%rbp)
mov    -0x3a(%rbp),%al
test   $0x1,%al
jne    126b <dqselect+0x16b>
jmp    127e <dqselect+0x17e>
jmp    1270 <dqselect+0x170>
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    122e <dqselect+0x12e>
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd -0x30(%rbp),%xmm0
jbe    12b6 <dqselect+0x1b6>
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
mov    %eax,-0x28(%rbp)
jmp    1190 <dqselect+0x90>
movsd  -0x30(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jne    12e8 <dqselect+0x1e8>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    134a <dqselect+0x24a>
mov    -0x28(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jle    12ff <dqselect+0x1ff>
mov    -0x28(%rbp),%eax
mov    %eax,-0xc(%rbp)
jmp    1333 <dqselect+0x233>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%ecx
mov    -0xc(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0x28(%rbp),%ecx
mov    -0x18(%rbp),%rax
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x18(%rbp)
mov    -0x28(%rbp),%ecx
mov    -0x1c(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x1c(%rbp)
jmp    1338 <dqselect+0x238>
jmp    115e <dqselect+0x5e>
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<dqselect>:
push   %r15
push   %r14
push   %r12
push   %rbx
xor    %r8d,%r8d
test   %edx,%edx
cmovs  %r8d,%edx
cmp    $0x2,%edi
jl     1220 <dqselect+0x120>
lea    -0x1(%rdi),%r9d
cmp    %r9d,%edx
cmovb  %edx,%r9d
movabs $0xffffffff00000000,%r10
ff ff ff
movabs $0x100000000,%r14
nopl   0x0(%rax,%rax,1)
lea    -0x1(%rdi),%r11d
movsd  (%rsi,%r11,8),%xmm0
mov    %r11d,%edx
xor    %r12d,%r12d
jmp    1168 <dqselect+0x68>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmp    %edx,%ebx
jge    11f0 <dqselect+0xf0>
mov    %r12,%rcx
shl    $0x20,%rcx
add    %r10,%rcx
movslq %r12d,%rax
movslq %r11d,%r15
lea    -0x1(%rax),%ebx
nopl   0x0(%rax,%rax,1)
add    %r14,%rcx
movsd  (%rsi,%rax,8),%xmm1
lea    0x1(%rax),%r12
add    $0x1,%ebx
ucomisd %xmm0,%xmm1
jb     119d <dqselect+0x9d>
cmp    %r15,%rax
mov    %r12,%rax
jl     1180 <dqselect+0x80>
ucomisd %xmm1,%xmm0
jbe    11b3 <dqselect+0xb3>
movsd  %xmm1,(%rsi,%r15,8)
sar    $0x20,%rcx
mov    %rcx,%r15
mov    %ebx,%r11d
add    $0xffffffffffffffff,%r12
movslq %edx,%rax
lea    0x1(%rax),%edx
nopl   (%rax)
movsd  (%rsi,%rax,8),%xmm1
add    $0xffffffff,%edx
ucomisd %xmm1,%xmm0
jb     11da <dqselect+0xda>
lea    -0x1(%rax),%rcx
cmp    %r15,%rax
mov    %rcx,%rax
jg     11c0 <dqselect+0xc0>
ucomisd %xmm0,%xmm1
jbe    1160 <dqselect+0x60>
movsd  %xmm1,(%rsi,%r15,8)
mov    %edx,%r11d
jmp    1160 <dqselect+0x60>
xchg   %ax,%ax
movslq %r11d,%rax
movsd  %xmm0,(%rsi,%rax,8)
cmp    %r9d,%eax
je     1224 <dqselect+0x124>
lea    0x1(%r11),%eax
sub    %eax,%edi
cmp    %r9d,%r11d
cmovg  %r11d,%edi
cmovg  %r8d,%eax
cltq
lea    (%rsi,%rax,8),%rsi
sub    %eax,%r9d
cmp    $0x1,%edi
jg     1140 <dqselect+0x40>
movsd  (%rsi),%xmm0
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define double @dqselect(i32 %0, double* nocapture %1, i32 %2) {
%4 = icmp sgt i32 %2, 0
%5 = select i1 %4, i32 %2, i32 0
%6 = add nsw i32 %0, -1
%7 = icmp sgt i32 %0, 1
br i1 %7, label %8, label %75
8: ; preds = %3
%9 = icmp ult i32 %5, %6
%10 = select i1 %9, i32 %5, i32 %6
br label %11
11: ; preds = %65, %8
%12 = phi i32 [ %73, %65 ], [ %10, %8 ]
%13 = phi double* [ %72, %65 ], [ %1, %8 ]
%14 = phi i32 [ %69, %65 ], [ %0, %8 ]
%15 = add nsw i32 %14, -1
%16 = zext i32 %15 to i64
%17 = getelementptr inbounds double, double* %13, i64 %16
%18 = load double, double* %17
br label %19
19: ; preds = %11, %58
%20 = phi i32 [ %59, %58 ], [ %15, %11 ]
%21 = phi i32 [ %54, %58 ], [ %15, %11 ]
%22 = phi i64 [ %27, %58 ], [ 0, %11 ]
%23 = shl i64 %22, 32
%24 = ashr exact i64 %23, 32
%25 = sext i32 %20 to i64
br label %26
26: ; preds = %26, %19
%27 = phi i64 [ %33, %26 ], [ %24, %19 ]
%28 = getelementptr inbounds double, double* %13, i64 %27
%29 = load double, double* %28
%30 = fcmp oge double %29, %18
%31 = icmp slt i64 %27, %25
%32 = select i1 %30, i1 %31, i1 false
%33 = add nsw i64 %27, 1
br i1 %32, label %26, label %34
34: ; preds = %26
%35 = trunc i64 %27 to i32
%36 = fcmp olt double %29, %18
br i1 %36, label %37, label %41
37: ; preds = %34
%38 = getelementptr inbounds double, double* %13, i64 %25
store double %29, double* %38
%39 = shl i64 %27, 32
%40 = ashr exact i64 %39, 32
br label %41
41: ; preds = %37, %34
%42 = phi i64 [ %40, %37 ], [ %25, %34 ]
%43 = phi i32 [ %35, %37 ], [ %20, %34 ]
%44 = sext i32 %21 to i64
br label %45
45: ; preds = %45, %41
%46 = phi i64 [ %52, %45 ], [ %44, %41 ]
%47 = getelementptr inbounds double, double* %13, i64 %46
%48 = load double, double* %47
%49 = fcmp ole double %48, %18
%50 = icmp sgt i64 %46, %42
%51 = select i1 %49, i1 %50, i1 false
%52 = add nsw i64 %46, -1
br i1 %51, label %45, label %53
53: ; preds = %45
%54 = trunc i64 %46 to i32
%55 = fcmp ogt double %48, %18
br i1 %55, label %56, label %58
56: ; preds = %53
%57 = getelementptr inbounds double, double* %13, i64 %42
store double %48, double* %57
br label %58
58: ; preds = %56, %53
%59 = phi i32 [ %54, %56 ], [ %43, %53 ]
%60 = icmp slt i32 %35, %54
br i1 %60, label %19, label %61
61: ; preds = %58
%62 = sext i32 %59 to i64
%63 = getelementptr inbounds double, double* %13, i64 %62
store double %18, double* %63
%64 = icmp eq i32 %59, %12
br i1 %64, label %78, label %65
65: ; preds = %61
%66 = icmp sgt i32 %59, %12
%67 = add nsw i32 %59, 1
%68 = sub nsw i32 %14, %67
%69 = select i1 %66, i32 %59, i32 %68
%70 = select i1 %66, i32 0, i32 %67
%71 = sext i32 %70 to i64
%72 = getelementptr double, double* %13, i64 %71
%73 = sub nsw i32 %12, %70
%74 = icmp sgt i32 %69, 1
br i1 %74, label %11, label %75
75: ; preds = %65, %3
%76 = phi double* [ %1, %3 ], [ %72, %65 ]
%77 = load double, double* %76
br label %78
78: ; preds = %61, %75
%79 = phi double [ %77, %75 ], [ %18, %61 ]
ret double %79
}