int cmp_double_array_idxs(void *qsort_thunk_vp, const void *xvp,
                          const void *yvp) {
  double *vals = (double *)qsort_thunk_vp;
  int x = *(int *)xvp, y = *(int *)yvp;
  return (((vals[x]) == (vals[y])) ? 0 : (((vals[x]) < (vals[y])) ? -1 : 1));
}


x86 assembly (clang, -O0):
<cmp_double_array_idxs>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x24(%rbp)
mov    -0x18(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
jne    115a <cmp_double_array_idxs+0x5a>
jp     115a <cmp_double_array_idxs+0x5a>
xor    %eax,%eax
mov    %eax,-0x2c(%rbp)
jmp    1188 <cmp_double_array_idxs+0x88>
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x20(%rbp),%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    $0x1,%eax
mov    $0xffffffff,%ecx
ucomisd %xmm1,%xmm0
cmova  %ecx,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<cmp_double_array_idxs>:
movslq (%rsi),%rax
movslq (%rdx),%rcx
movsd  (%rdi,%rax,8),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
xor    %ecx,%ecx
ucomisd %xmm0,%xmm1
setbe  %cl
xor    %eax,%eax
ucomisd %xmm1,%xmm0
lea    -0x1(%rcx,%rcx,1),%ecx
cmovne %ecx,%eax
cmovp  %ecx,%eax
ret

LLVM IR (-O0):
define i32 @cmp_double_array_idxs(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca double*
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8* %2, i8** %6
%10 = load i8*, i8** %4
%11 = bitcast i8* %10 to double*
store double* %11, double** %7
%12 = load i8*, i8** %5
%13 = bitcast i8* %12 to i32*
%14 = load i32, i32* %13
store i32 %14, i32* %8
%15 = load i8*, i8** %6
%16 = bitcast i8* %15 to i32*
%17 = load i32, i32* %16
store i32 %17, i32* %9
%18 = load double*, double** %7
%19 = load i32, i32* %8
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds double, double* %18, i64 %20
%22 = load double, double* %21
%23 = load double*, double** %7
%24 = load i32, i32* %9
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds double, double* %23, i64 %25
%27 = load double, double* %26
%28 = fcmp oeq double %22, %27
br i1 %28, label %29, label %30
29: ; preds = %3
br label %44
30: ; preds = %3
%31 = load double*, double** %7
%32 = load i32, i32* %8
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds double, double* %31, i64 %33
%35 = load double, double* %34
%36 = load double*, double** %7
%37 = load i32, i32* %9
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double, double* %36, i64 %38
%40 = load double, double* %39
%41 = fcmp olt double %35, %40
%42 = zext i1 %41 to i64
%43 = select i1 %41, i32 -1, i32 1
br label %44
44: ; preds = %30, %29
%45 = phi i32 [ 0, %29 ], [ %43, %30 ]
ret i32 %45
}

LLVM IR (-O2):
define i32 @cmp_double_array_idxs(i8* nocapture %0, i8* nocapture %1, i8* nocapture %2) {
%4 = bitcast i8* %0 to double*
%5 = bitcast i8* %1 to i32*
%6 = load i32, i32* %5
%7 = bitcast i8* %2 to i32*
%8 = load i32, i32* %7
%9 = sext i32 %6 to i64
%10 = getelementptr inbounds double, double* %4, i64 %9
%11 = load double, double* %10
%12 = sext i32 %8 to i64
%13 = getelementptr inbounds double, double* %4, i64 %12
%14 = load double, double* %13
%15 = fcmp oeq double %11, %14
%16 = fcmp olt double %11, %14
%17 = select i1 %16, i32 -1, i32 1
%18 = select i1 %15, i32 0, i32 %17
ret i32 %18
}