int fgtx(double *tab, int lo, int hi, double val) {
  int k;
  if (val >= tab[hi])
    return hi + 1;
  if (val < tab[lo])
    return lo;
  k = (lo + hi) / 2;
  if (val <= tab[k])
    return fgtx(tab, lo + 1, k, val);
  return fgtx(tab, k, hi - 1, val);
}


x86 assembly (clang, -O0):
<fgtx>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
jb     114d <fgtx+0x3d>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    11da <fgtx+0xca>
movsd  -0x20(%rbp),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jbe    1174 <fgtx+0x64>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11da <fgtx+0xca>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x24(%rbp)
movsd  -0x20(%rbp),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
ucomisd %xmm1,%xmm0
jb     11c0 <fgtx+0xb0>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
add    $0x1,%esi
mov    -0x24(%rbp),%edx
movsd  -0x20(%rbp),%xmm0
call   1030 <fgtx@plt>
mov    %eax,-0x4(%rbp)
jmp    11da <fgtx+0xca>
mov    -0x10(%rbp),%rdi
mov    -0x24(%rbp),%esi
mov    -0x18(%rbp),%edx
sub    $0x1,%edx
movsd  -0x20(%rbp),%xmm0
call   1030 <fgtx@plt>
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fgtx>:
movslq %edx,%rcx
ucomisd (%rdi,%rcx,8),%xmm0
jae    1150 <fgtx+0x50>
mov    %esi,%eax
jmp    111f <fgtx+0x1f>
xchg   %ax,%ax
add    $0x1,%eax
movslq %ecx,%rdx
ucomisd (%rdi,%rdx,8),%xmm0
mov    %ecx,%edx
jae    1152 <fgtx+0x52>
movslq %eax,%rcx
movsd  (%rdi,%rcx,8),%xmm1
ucomisd %xmm0,%xmm1
ja     1157 <fgtx+0x57>
lea    (%rdx,%rax,1),%esi
mov    %esi,%ecx
shr    $0x1f,%ecx
add    %esi,%ecx
sar    %ecx
movslq %ecx,%rsi
movsd  (%rdi,%rsi,8),%xmm1
ucomisd %xmm0,%xmm1
jae    1110 <fgtx+0x10>
add    $0xffffffff,%edx
mov    %ecx,%eax
mov    %edx,%ecx
jmp    1113 <fgtx+0x13>
mov    %edx,%ecx
add    $0x1,%ecx
mov    %ecx,%eax
ret

LLVM IR (-O0):
define i32 @fgtx(double* %0, i32 %1, i32 %2, double %3) {
%5 = alloca i32
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
%10 = alloca i32
store double* %0, double** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store double %3, double* %9
%11 = load double, double* %9
%12 = load double*, double** %6
%13 = load i32, i32* %8
%14 = sext i32 %13 to i64
%15 = getelementptr inbounds double, double* %12, i64 %14
%16 = load double, double* %15
%17 = fcmp oge double %11, %16
br i1 %17, label %18, label %21
18: ; preds = %4
%19 = load i32, i32* %8
%20 = add nsw i32 %19, 1
store i32 %20, i32* %5
br label %57
21: ; preds = %4
%22 = load double, double* %9
%23 = load double*, double** %6
%24 = load i32, i32* %7
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds double, double* %23, i64 %25
%27 = load double, double* %26
%28 = fcmp olt double %22, %27
br i1 %28, label %29, label %31
29: ; preds = %21
%30 = load i32, i32* %7
store i32 %30, i32* %5
br label %57
31: ; preds = %21
%32 = load i32, i32* %7
%33 = load i32, i32* %8
%34 = add nsw i32 %32, %33
%35 = sdiv i32 %34, 2
store i32 %35, i32* %10
%36 = load double, double* %9
%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
%42 = fcmp ole double %36, %41
br i1 %42, label %43, label %50
43: ; preds = %31
%44 = load double*, double** %6
%45 = load i32, i32* %7
%46 = add nsw i32 %45, 1
%47 = load i32, i32* %10
%48 = load double, double* %9
%49 = call i32 @fgtx(double* %44, i32 %46, i32 %47, double %48)
store i32 %49, i32* %5
br label %57
50: ; preds = %31
%51 = load double*, double** %6
%52 = load i32, i32* %10
%53 = load i32, i32* %8
%54 = sub nsw i32 %53, 1
%55 = load double, double* %9
%56 = call i32 @fgtx(double* %51, i32 %52, i32 %54, double %55)
store i32 %56, i32* %5
br label %57
57: ; preds = %50, %43, %29, %18
%58 = load i32, i32* %5
ret i32 %58
}

LLVM IR (-O2):
define i32 @fgtx(double* %0, i32 %1, i32 %2, double %3) {
%5 = sext i32 %2 to i64
%6 = getelementptr inbounds double, double* %0, i64 %5
%7 = load double, double* %6
%8 = fcmp ugt double %7, %3
br i1 %8, label %12, label %9
9: ; preds = %19, %4
%10 = phi i32 [ %2, %4 ], [ %29, %19 ]
%11 = add nsw i32 %10, 1
br label %34
12: ; preds = %4, %19
%13 = phi i32 [ %29, %19 ], [ %2, %4 ]
%14 = phi i32 [ %28, %19 ], [ %1, %4 ]
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds double, double* %0, i64 %15
%17 = load double, double* %16
%18 = fcmp ogt double %17, %3
br i1 %18, label %34, label %19
19: ; preds = %12
%20 = add nsw i32 %13, %14
%21 = sdiv i32 %20, 2
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds double, double* %0, i64 %22
%24 = load double, double* %23
%25 = fcmp ult double %24, %3
%26 = add nsw i32 %14, 1
%27 = add nsw i32 %13, -1
%28 = select i1 %25, i32 %21, i32 %26
%29 = select i1 %25, i32 %27, i32 %21
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds double, double* %0, i64 %30
%32 = load double, double* %31
%33 = fcmp ugt double %32, %3
br i1 %33, label %12, label %9
34: ; preds = %12, %9
%35 = phi i32 [ %11, %9 ], [ %14, %12 ]
ret i32 %35
}