#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ Fib;

/* Variables and functions */
#define INT_MAX 128
int binsrch_geq(int const *, int, int);
int fibsrch(const int *arr, int n, int val) {
  register int k, idx, offs;
  static int prevn = -1, prevk = -1;
  const static int Fib[47 + 1] = {
      0,         1,         1,         2,          3,          5,
      8,         13,        21,        34,         55,         89,
      144,       233,       377,       610,        987,        1597,
      2584,      4181,      6765,      10946,      17711,      28657,
      46368,     75025,     121393,    196418,     317811,     514229,
      832040,    1346269,   2178309,   3524578,    5702887,    9227465,
      14930352,  24157817,  39088169,  63245986,   102334155,  165580141,
      267914296, 433494437, 701408733, 1134903170, 1836311903, INT_MAX};
  if (n != prevn) {
    k = (n > 1) ? binsrch_geq(Fib, sizeof(Fib) / sizeof(int), n) : 1;
    prevk = k;
    prevn = n;
  } else
    k = prevk;
  for (offs = 0; k > 0;) {
    idx = offs + Fib[--k];
    if (idx >= n || val < arr[idx])
      continue;
    else if (val > arr[idx]) {
      offs = idx;
      --k;
    } else
      return idx;
  }
  return -1;
}


x86 assembly (clang, -O0):
<fibsrch>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    -0x14(%rbp),%eax
cmp    0x2efd(%rip),%eax
je     1181 <fibsrch+0x71>
cmpl   $0x1,-0x14(%rbp)
jle    1157 <fibsrch+0x47>
mov    -0x14(%rbp),%edx
lea    0xebb(%rip),%rdi
mov    $0x30,%esi
call   1030 <binsrch_geq@plt>
mov    %eax,-0x28(%rbp)
jmp    1164 <fibsrch+0x54>
mov    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1164 <fibsrch+0x54>
mov    -0x28(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,0x2eb9(%rip)
mov    -0x14(%rbp),%eax
mov    %eax,0x2eac(%rip)
jmp    118a <fibsrch+0x7a>
mov    0x2ea5(%rip),%eax
mov    %eax,-0x1c(%rbp)
movl   $0x0,-0x24(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jle    1219 <fibsrch+0x109>
mov    -0x24(%rbp),%eax
mov    -0x1c(%rbp),%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x1c(%rbp)
movslq %ecx,%rdx
lea    0xe4f(%rip),%rcx
add    (%rcx,%rdx,4),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11d7 <fibsrch+0xc7>
mov    -0x18(%rbp),%eax
mov    -0x10(%rbp),%rcx
movslq -0x20(%rbp),%rdx
cmp    (%rcx,%rdx,4),%eax
jge    11dc <fibsrch+0xcc>
jmp    1191 <fibsrch+0x81>
mov    -0x18(%rbp),%eax
mov    -0x10(%rbp),%rcx
movslq -0x20(%rbp),%rdx
cmp    (%rcx,%rdx,4),%eax
jle    1204 <fibsrch+0xf4>
mov    -0x20(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    120f <fibsrch+0xff>
mov    -0x20(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1220 <fibsrch+0x110>
jmp    1214 <fibsrch+0x104>
jmp    1191 <fibsrch+0x81>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fibsrch>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %edx,%r14d
mov    %esi,%ebp
mov    %rdi,%r15
cmp    %esi,0x2f03(%rip)
jne    1130 <fibsrch+0x20>
mov    0x2efe(%rip),%r9d
jmp    115e <fibsrch+0x4e>
mov    $0x1,%r9d
cmp    $0x2,%ebp
jl     1151 <fibsrch+0x41>
lea    0xebe(%rip),%rdi
mov    $0x30,%esi
mov    %ebp,%edx
call   1030 <binsrch_geq@plt>
mov    %eax,%r9d
mov    %r9d,0x2ed4(%rip)
mov    %ebp,0x2eca(%rip)
mov    $0xffffffff,%eax
test   %r9d,%r9d
jle    11b0 <fibsrch+0xa0>
xor    %edi,%edi
lea    0xe8f(%rip),%r8
mov    %edi,%esi
lea    -0x1(%r9),%ecx
lea    (%r8,%rcx,4),%rdx
mov    %r9d,%ecx
jmp    118e <fibsrch+0x7e>
lea    -0x1(%rcx),%edi
add    $0xfffffffffffffffc,%rdx
cmp    $0x1,%ecx
mov    %edi,%ecx
jle    11b0 <fibsrch+0xa0>
movslq (%rdx),%rbx
movslq %esi,%rdi
add    %rbx,%rdi
cmp    %ebp,%edi
jge    1180 <fibsrch+0x70>
cmp    %r14d,(%r15,%rdi,4)
jg     1180 <fibsrch+0x70>
jge    11ae <fibsrch+0x9e>
lea    -0x2(%rcx),%r9d
cmp    $0x3,%ecx
jge    1171 <fibsrch+0x61>
jmp    11b0 <fibsrch+0xa0>
mov    %edi,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@fibsrch.prevn = internal global i32 -1
@fibsrch.prevk = internal global i32 -1
@fibsrch.Fib = internal constant [48 x i32] [i32 0, i32 1, i32 1, i32 2, i32 3, i32 5, i32 8, i32 13, i32 21, i32 34, i32 55, i32 89, i32 144, i32 233, i32 377, i32 610, i32 987, i32 1597, i32 2584, i32 4181, i32 6765, i32 10946, i32 17711, i32 28657, i32 46368, i32 75025, i32 121393, i32 196418, i32 317811, i32 514229, i32 832040, i32 1346269, i32 2178309, i32 3524578, i32 5702887, i32 9227465, i32 14930352, i32 24157817, i32 39088169, i32 63245986, i32 102334155, i32 165580141, i32 267914296, i32 433494437, i32 701408733, i32 1134903170, i32 1836311903, i32 128]
define i32 @fibsrch(i32* %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
store i32* %0, i32** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
%11 = load i32, i32* %6
%12 = load i32, i32* @fibsrch.prevn
%13 = icmp ne i32 %11, %12
br i1 %13, label %14, label %25
14: ; preds = %3
%15 = load i32, i32* %6
%16 = icmp sgt i32 %15, 1
br i1 %16, label %17, label %20
17: ; preds = %14
%18 = load i32, i32* %6
%19 = call i32 @binsrch_geq(i32* getelementptr inbounds ([48 x i32], [48 x i32]* @fibsrch.Fib, i64 0, i64 0), i32 48, i32 %18)
br label %21
20: ; preds = %14
br label %21
21: ; preds = %20, %17
%22 = phi i32 [ %19, %17 ], [ 1, %20 ]
store i32 %22, i32* %8
%23 = load i32, i32* %8
store i32 %23, i32* @fibsrch.prevk
%24 = load i32, i32* %6
store i32 %24, i32* @fibsrch.prevn
br label %27
25: ; preds = %3
%26 = load i32, i32* @fibsrch.prevk
store i32 %26, i32* %8
br label %27
27: ; preds = %25, %21
store i32 0, i32* %10
br label %28
28: ; preds = %66, %50, %27
%29 = load i32, i32* %8
%30 = icmp sgt i32 %29, 0
br i1 %30, label %31, label %67
31: ; preds = %28
%32 = load i32, i32* %10
%33 = load i32, i32* %8
%34 = add nsw i32 %33, -1
store i32 %34, i32* %8
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds [48 x i32], [48 x i32]* @fibsrch.Fib, i64 0, i64 %35
%37 = load i32, i32* %36
%38 = add nsw i32 %32, %37
store i32 %38, i32* %9
%39 = load i32, i32* %9
%40 = load i32, i32* %6
%41 = icmp sge i32 %39, %40
br i1 %41, label %50, label %42
42: ; preds = %31
%43 = load i32, i32* %7
%44 = load i32*, i32** %5
%45 = load i32, i32* %9
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds i32, i32* %44, i64 %46
%48 = load i32, i32* %47
%49 = icmp slt i32 %43, %48
br i1 %49, label %50, label %51
50: ; preds = %42, %31
br label %28
51: ; preds = %42
%52 = load i32, i32* %7
%53 = load i32*, i32** %5
%54 = load i32, i32* %9
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %53, i64 %55
%57 = load i32, i32* %56
%58 = icmp sgt i32 %52, %57
br i1 %58, label %59, label %63
59: ; preds = %51
%60 = load i32, i32* %9
store i32 %60, i32* %10
%61 = load i32, i32* %8
%62 = add nsw i32 %61, -1
store i32 %62, i32* %8
br label %65
63: ; preds = %51
%64 = load i32, i32* %9
store i32 %64, i32* %4
br label %68
65: ; preds = %59
br label %66
66: ; preds = %65
br label %28
67: ; preds = %28
store i32 -1, i32* %4
br label %68
68: ; preds = %67, %63
%69 = load i32, i32* %4
ret i32 %69
}

LLVM IR (-O2):
@fibsrch.prevn = internal unnamed_addr global i32 -1
@fibsrch.prevk = internal unnamed_addr global i32 -1
@fibsrch.Fib = internal constant [48 x i32] [i32 0, i32 1, i32 1, i32 2, i32 3, i32 5, i32 8, i32 13, i32 21, i32 34, i32 55, i32 89, i32 144, i32 233, i32 377, i32 610, i32 987, i32 1597, i32 2584, i32 4181, i32 6765, i32 10946, i32 17711, i32 28657, i32 46368, i32 75025, i32 121393, i32 196418, i32 317811, i32 514229, i32 832040, i32 1346269, i32 2178309, i32 3524578, i32 5702887, i32 9227465, i32 14930352, i32 24157817, i32 39088169, i32 63245986, i32 102334155, i32 165580141, i32 267914296, i32 433494437, i32 701408733, i32 1134903170, i32 1836311903, i32 128]
define i32 @fibsrch(i32* nocapture %0, i32 %1, i32 %2) {
%4 = load i32, i32* @fibsrch.prevn
%5 = icmp eq i32 %4, %1
br i1 %5, label %12, label %6
6: ; preds = %3
%7 = icmp sgt i32 %1, 1
br i1 %7, label %8, label %10
8: ; preds = %6
%9 = tail call i32 @binsrch_geq(i32* getelementptr inbounds ([48 x i32], [48 x i32]* @fibsrch.Fib, i64 0, i64 0), i32 48, i32 %1)
br label %10
10: ; preds = %6, %8
%11 = phi i32 [ %9, %8 ], [ 1, %6 ]
store i32 %11, i32* @fibsrch.prevk
store i32 %1, i32* @fibsrch.prevn
br label %14
12: ; preds = %3
%13 = load i32, i32* @fibsrch.prevk
br label %14
14: ; preds = %12, %10
%15 = phi i32 [ %11, %10 ], [ %13, %12 ]
%16 = icmp sgt i32 %15, 0
br i1 %16, label %20, label %43
17: ; preds = %40
%18 = add nsw i32 %41, -2
%19 = icmp sgt i32 %41, 2
br i1 %19, label %20, label %43
20: ; preds = %14, %17
%21 = phi i32 [ %30, %17 ], [ 0, %14 ]
%22 = phi i32 [ %18, %17 ], [ %15, %14 ]
%23 = zext i32 %22 to i64
br label %24
24: ; preds = %20, %37
%25 = phi i64 [ %23, %20 ], [ %26, %37 ]
%26 = add nsw i64 %25, -1
%27 = and i64 %26, 4294967295
%28 = getelementptr inbounds [48 x i32], [48 x i32]* @fibsrch.Fib, i64 0, i64 %27
%29 = load i32, i32* %28
%30 = add nsw i32 %29, %21
%31 = icmp slt i32 %30, %1
br i1 %31, label %32, label %37
32: ; preds = %24
%33 = sext i32 %30 to i64
%34 = getelementptr inbounds i32, i32* %0, i64 %33
%35 = load i32, i32* %34
%36 = icmp sgt i32 %35, %2
br i1 %36, label %37, label %40
37: ; preds = %32, %24
%38 = trunc i64 %25 to i32
%39 = icmp sgt i32 %38, 1
br i1 %39, label %24, label %43
40: ; preds = %32
%41 = trunc i64 %25 to i32
%42 = icmp slt i32 %35, %2
br i1 %42, label %17, label %43
43: ; preds = %40, %17, %37, %14
%44 = phi i32 [ -1, %14 ], [ -1, %37 ], [ -1, %17 ], [ %30, %40 ]
ret i32 %44
}