long find_element(double x, long nelem, const double *restrict array) {
  long ii;
  long mid = 0;
  long first = 1;
  long last = nelem;
  if (array[0] < array[nelem - 1]) {
    if (x < array[0] || x > array[nelem - 1])
      return (nelem);
    for (ii = 1; ii < nelem; ++ii) {
      mid = (first + last) >> 1;
      if (!(x < array[mid - 1] || x > array[mid]))
        break;
      if (x > array[mid])
        first = mid;
      else
        last = mid;
    }
  } else {
    if (x < array[nelem - 1] || x > array[0])
      return (nelem);
    for (ii = 1; ii < nelem; ++ii) {
      mid = (first + last) >> 1;
      if (!(x < array[mid] || x > array[mid - 1]))
        break;
      if (x < array[mid])
        first = mid;
      else
        last = mid;
    }
  }
  if (mid > 1 && (!(x < array[mid - 1] || array[mid - 1] < x)))
    mid--;
  return (mid);
}


x86 assembly (clang, -O0):
<find_element>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
mov    %rdi,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x1,-0x38(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    1237 <find_element+0x137>
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
ucomisd %xmm1,%xmm0
ja     117f <find_element+0x7f>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
ucomisd (%rax,%rcx,8),%xmm0
jbe    118c <find_element+0x8c>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1385 <find_element+0x285>
movq   $0x1,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    1232 <find_element+0x132>
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
ja     11ef <find_element+0xef>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
ja     11ef <find_element+0xef>
jmp    1232 <find_element+0x132>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
jbe    1214 <find_element+0x114>
mov    -0x30(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    121c <find_element+0x11c>
mov    -0x30(%rbp),%rax
mov    %rax,-0x40(%rbp)
jmp    1221 <find_element+0x121>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1194 <find_element+0x94>
jmp    1326 <find_element+0x226>
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
ja     126a <find_element+0x16a>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
ucomisd (%rax),%xmm0
jbe    1277 <find_element+0x177>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1385 <find_element+0x285>
movq   $0x1,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    1321 <find_element+0x221>
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
ja     12da <find_element+0x1da>
movsd  -0x10(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
ucomisd (%rax,%rcx,8),%xmm0
ja     12da <find_element+0x1da>
jmp    1321 <find_element+0x221>
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    1303 <find_element+0x203>
mov    -0x30(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    130b <find_element+0x20b>
mov    -0x30(%rbp),%rax
mov    %rax,-0x40(%rbp)
jmp    1310 <find_element+0x210>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    127f <find_element+0x17f>
jmp    1326 <find_element+0x226>
cmpq   $0x1,-0x30(%rbp)
jle    137d <find_element+0x27d>
movsd  -0x10(%rbp),%xmm1
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
ja     137d <find_element+0x27d>
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm1
movsd  -0x10(%rbp),%xmm0
ucomisd %xmm1,%xmm0
ja     137d <find_element+0x27d>
mov    -0x30(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<find_element>:
mov    %rdi,%rax
movsd  (%rsi),%xmm1
movsd  -0x8(%rsi,%rdi,8),%xmm2
ucomisd %xmm1,%xmm2
jbe    117c <find_element+0x7c>
ucomisd %xmm0,%xmm1
ja     11e0 <find_element+0xe0>
ucomisd %xmm2,%xmm0
ja     11e0 <find_element+0xe0>
cmp    $0x2,%rax
jl     11e1 <find_element+0xe1>
lea    -0x1(%rax),%rdx
mov    $0x1,%edi
jmp    114d <find_element+0x4d>
nopl   0x0(%rax)
mov    %r8,%rdi
add    $0xffffffffffffffff,%rdx
je     11cc <find_element+0xcc>
lea    (%rax,%rdi,1),%rcx
sar    %rcx
movsd  -0x8(%rsi,%rcx,8),%xmm2
movsd  (%rsi,%rcx,8),%xmm1
ucomisd %xmm0,%xmm2
ja     116b <find_element+0x6b>
ucomisd %xmm1,%xmm0
jbe    11cc <find_element+0xcc>
ucomisd %xmm1,%xmm0
mov    %rcx,%r8
ja     1140 <find_element+0x40>
mov    %rdi,%r8
mov    %rcx,%rax
jmp    1140 <find_element+0x40>
ucomisd %xmm0,%xmm2
ja     11e0 <find_element+0xe0>
ucomisd %xmm1,%xmm0
ja     11e0 <find_element+0xe0>
cmp    $0x2,%rax
jl     11e1 <find_element+0xe1>
lea    -0x1(%rax),%rdx
mov    $0x1,%r8d
jmp    11a9 <find_element+0xa9>
nopw   0x0(%rax,%rax,1)
mov    %rdi,%r8
add    $0xffffffffffffffff,%rdx
je     11cc <find_element+0xcc>
lea    (%rax,%r8,1),%rcx
sar    %rcx
movsd  (%rsi,%rcx,8),%xmm1
ucomisd %xmm0,%xmm1
mov    %rcx,%rdi
ja     11a0 <find_element+0xa0>
ucomisd -0x8(%rsi,%rcx,8),%xmm0
mov    %rcx,%rax
mov    %r8,%rdi
ja     11a0 <find_element+0xa0>
cmp    $0x2,%rcx
jl     11e4 <find_element+0xe4>
ucomisd -0x8(%rsi,%rcx,8),%xmm0
lea    -0x1(%rcx),%rax
cmovne %rcx,%rax
ret
xor    %eax,%eax
ret
mov    %rcx,%rax
ret

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

LLVM IR (-O2):
define i64 @find_element(double %0, i64 %1, double* noalias nocapture %2) {
%4 = load double, double* %2
%5 = add nsw i64 %1, -1
%6 = getelementptr inbounds double, double* %2, i64 %5
%7 = load double, double* %6
%8 = fcmp olt double %4, %7
br i1 %8, label %9, label %35
9: ; preds = %3
%10 = fcmp ogt double %4, %0
%11 = fcmp olt double %7, %0
%12 = select i1 %10, i1 true, i1 %11
br i1 %12, label %69, label %13
13: ; preds = %9
%14 = icmp sgt i64 %1, 1
br i1 %14, label %15, label %69
15: ; preds = %13, %29
%16 = phi i64 [ %32, %29 ], [ %1, %13 ]
%17 = phi i64 [ %31, %29 ], [ 1, %13 ]
%18 = phi i64 [ %33, %29 ], [ 1, %13 ]
%19 = add nsw i64 %16, %17
%20 = ashr i64 %19, 1
%21 = add nsw i64 %20, -1
%22 = getelementptr inbounds double, double* %2, i64 %21
%23 = load double, double* %22
%24 = fcmp ogt double %23, %0
%25 = getelementptr inbounds double, double* %2, i64 %20
%26 = load double, double* %25
%27 = fcmp olt double %26, %0
%28 = select i1 %24, i1 true, i1 %27
br i1 %28, label %29, label %60
29: ; preds = %15
%30 = fcmp olt double %26, %0
%31 = select i1 %30, i64 %20, i64 %17
%32 = select i1 %30, i64 %16, i64 %20
%33 = add nuw nsw i64 %18, 1
%34 = icmp eq i64 %33, %1
br i1 %34, label %60, label %15
35: ; preds = %3
%36 = fcmp ogt double %7, %0
%37 = fcmp olt double %4, %0
%38 = select i1 %36, i1 true, i1 %37
br i1 %38, label %69, label %39
39: ; preds = %35
%40 = icmp sgt i64 %1, 1
br i1 %40, label %41, label %69
41: ; preds = %39, %55
%42 = phi i64 [ %56, %55 ], [ %1, %39 ]
%43 = phi i64 [ %57, %55 ], [ 1, %39 ]
%44 = phi i64 [ %58, %55 ], [ 1, %39 ]
%45 = add nsw i64 %42, %43
%46 = ashr i64 %45, 1
%47 = getelementptr inbounds double, double* %2, i64 %46
%48 = load double, double* %47
%49 = fcmp ogt double %48, %0
br i1 %49, label %55, label %50
50: ; preds = %41
%51 = add nsw i64 %46, -1
%52 = getelementptr inbounds double, double* %2, i64 %51
%53 = load double, double* %52
%54 = fcmp olt double %53, %0
br i1 %54, label %55, label %60
55: ; preds = %50, %41
%56 = phi i64 [ %46, %50 ], [ %42, %41 ]
%57 = phi i64 [ %43, %50 ], [ %46, %41 ]
%58 = add nuw nsw i64 %44, 1
%59 = icmp eq i64 %58, %1
br i1 %59, label %60, label %41
60: ; preds = %50, %55, %29, %15
%61 = phi i64 [ %20, %15 ], [ %20, %29 ], [ %46, %55 ], [ %46, %50 ]
%62 = icmp sgt i64 %61, 1
br i1 %62, label %63, label %69
63: ; preds = %60
%64 = add nsw i64 %61, -1
%65 = getelementptr inbounds double, double* %2, i64 %64
%66 = load double, double* %65
%67 = fcmp one double %66, %0
%68 = select i1 %67, i64 %61, i64 %64
br label %69
69: ; preds = %39, %13, %63, %60, %35, %9
%70 = phi i64 [ %1, %9 ], [ %1, %35 ], [ %61, %60 ], [ %68, %63 ], [ 0, %13 ], [ 0, %39 ]
ret i64 %70
}