char BinSearch(unsigned short *src, unsigned char len, unsigned short key) {
  unsigned char low, high, mid;
  while ((len > 1) && (src[len - 1] == 0))
    len--;
  low = 0;
  high = len - 1;
  if ((key < src[low]) || (key > src[high]))
    return -1;
  if (key == src[low])
    return low;
  if (key == src[high])
    return high;
  while (low < high) {
    mid = low + ((high - low) / 2);
    if (key == src[mid])
      return mid;
    if (key < src[mid]) {
      high = mid - 1;
      if (key == src[high])
        return high;
    } else {
      low = mid + 1;
      if (key == src[low])
        return low;
    }
  }
  return -1;
}


x86 assembly (clang, -O0):
<BinSearch>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %sil,%cl
mov    %rdi,-0x10(%rbp)
mov    %cl,-0x11(%rbp)
mov    %ax,-0x14(%rbp)
movzbl -0x11(%rbp),%ecx
xor    %eax,%eax
cmp    $0x1,%ecx
mov    %al,-0x18(%rbp)
jle    1142 <BinSearch+0x42>
mov    -0x10(%rbp),%rax
movzbl -0x11(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movzwl (%rax,%rcx,2),%eax
cmp    $0x0,%eax
sete   %al
mov    %al,-0x18(%rbp)
mov    -0x18(%rbp),%al
test   $0x1,%al
jne    1152 <BinSearch+0x52>
jmp    115f <BinSearch+0x5f>
mov    -0x11(%rbp),%al
add    $0xff,%al
mov    %al,-0x11(%rbp)
jmp    1115 <BinSearch+0x15>
movb   $0x0,-0x15(%rbp)
movzbl -0x11(%rbp),%eax
sub    $0x1,%eax
mov    %al,-0x16(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x15(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jl     119d <BinSearch+0x9d>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x16(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jle    11a6 <BinSearch+0xa6>
movb   $0xff,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x15(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    11c9 <BinSearch+0xc9>
mov    -0x15(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x16(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    11ec <BinSearch+0xec>
mov    -0x16(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
jmp    11f1 <BinSearch+0xf1>
movzbl -0x15(%rbp),%eax
movzbl -0x16(%rbp),%ecx
cmp    %ecx,%eax
jge    12c8 <BinSearch+0x1c8>
movzbl -0x15(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movzbl -0x16(%rbp),%eax
movzbl -0x15(%rbp),%ecx
sub    %ecx,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x1c(%rbp),%eax
add    %ecx,%eax
mov    %al,-0x17(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x17(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    1247 <BinSearch+0x147>
mov    -0x17(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x17(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jge    1291 <BinSearch+0x191>
movzbl -0x17(%rbp),%eax
sub    $0x1,%eax
mov    %al,-0x16(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x16(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    128c <BinSearch+0x18c>
mov    -0x16(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
jmp    12c3 <BinSearch+0x1c3>
movzbl -0x17(%rbp),%eax
add    $0x1,%eax
mov    %al,-0x15(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzbl -0x15(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    12be <BinSearch+0x1be>
mov    -0x15(%rbp),%al
mov    %al,-0x1(%rbp)
jmp    12cc <BinSearch+0x1cc>
jmp    12c3 <BinSearch+0x1c3>
jmp    11f1 <BinSearch+0xf1>
movb   $0xff,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<BinSearch>:
cmp    $0x2,%sil
jb     112b <BinSearch+0x2b>
cs nopw 0x0(%rax,%rax,1)
movzbl %sil,%eax
add    $0xffffffff,%eax
cmpw   $0x0,(%rdi,%rax,2)
jne    112b <BinSearch+0x2b>
add    $0xff,%sil
cmp    $0x1,%sil
ja     1110 <BinSearch+0x10>
mov    $0x1,%sil
movzwl (%rdi),%eax
cmp    %dx,%ax
ja     1144 <BinSearch+0x44>
add    $0xff,%sil
movzbl %sil,%ecx
movzwl (%rdi,%rcx,2),%ecx
cmp    %dx,%cx
jae    1147 <BinSearch+0x47>
mov    $0xff,%al
ret
cmp    %dx,%ax
jne    114f <BinSearch+0x4f>
xor    %eax,%eax
ret
cmp    %dx,%cx
jne    1157 <BinSearch+0x57>
mov    %esi,%eax
ret
test   %sil,%sil
je     1144 <BinSearch+0x44>
xor    %r8d,%r8d
nop
movzbl %r8b,%eax
movzbl %sil,%ecx
sub    %eax,%ecx
movzwl %cx,%r9d
mov    %r9d,%ecx
shr    $0xf,%ecx
add    %r9d,%ecx
shr    %ecx
add    %cl,%al
movzbl %al,%ecx
cmp    %dx,(%rdi,%rcx,2)
je     1146 <BinSearch+0x46>
jbe    1190 <BinSearch+0x90>
add    $0xff,%al
movzbl %al,%ecx
mov    %eax,%esi
jmp    1198 <BinSearch+0x98>
nop
add    $0x1,%al
movzbl %al,%ecx
mov    %eax,%r8d
cmp    %dx,(%rdi,%rcx,2)
je     1146 <BinSearch+0x46>
cmp    %r8b,%sil
ja     1160 <BinSearch+0x60>
jmp    1144 <BinSearch+0x44>

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

LLVM IR (-O2):
define signext i8 @BinSearch(i16* nocapture %0, i8 zeroext %1, i16 zeroext %2) {
%4 = icmp ugt i8 %1, 1
br i1 %4, label %5, label %16
5: ; preds = %3, %13
%6 = phi i8 [ %14, %13 ], [ %1, %3 ]
%7 = zext i8 %6 to i64
%8 = add nuw nsw i64 %7, 4294967295
%9 = and i64 %8, 4294967295
%10 = getelementptr inbounds i16, i16* %0, i64 %9
%11 = load i16, i16* %10
%12 = icmp eq i16 %11, 0
br i1 %12, label %13, label %16
13: ; preds = %5
%14 = add i8 %6, -1
%15 = icmp ugt i8 %14, 1
br i1 %15, label %5, label %16
16: ; preds = %5, %13, %3
%17 = phi i8 [ %1, %3 ], [ 1, %13 ], [ %6, %5 ]
%18 = add i8 %17, -1
%19 = load i16, i16* %0
%20 = icmp ugt i16 %19, %2
br i1 %20, label %63, label %21
21: ; preds = %16
%22 = zext i8 %18 to i64
%23 = getelementptr inbounds i16, i16* %0, i64 %22
%24 = load i16, i16* %23
%25 = icmp ult i16 %24, %2
br i1 %25, label %63, label %26
26: ; preds = %21
%27 = icmp eq i16 %19, %2
br i1 %27, label %63, label %28
28: ; preds = %26
%29 = icmp eq i16 %24, %2
br i1 %29, label %63, label %30
30: ; preds = %28
%31 = icmp eq i8 %18, 0
br i1 %31, label %63, label %32
32: ; preds = %30, %59
%33 = phi i8 [ %61, %59 ], [ %18, %30 ]
%34 = phi i8 [ %60, %59 ], [ 0, %30 ]
%35 = zext i8 %34 to i16
%36 = zext i8 %33 to i16
%37 = sub nsw i16 %36, %35
%38 = sdiv i16 %37, 2
%39 = trunc i16 %38 to i8
%40 = add i8 %34, %39
%41 = zext i8 %40 to i64
%42 = getelementptr inbounds i16, i16* %0, i64 %41
%43 = load i16, i16* %42
%44 = icmp eq i16 %43, %2
br i1 %44, label %63, label %45
45: ; preds = %32
%46 = icmp ugt i16 %43, %2
br i1 %46, label %47, label %53
47: ; preds = %45
%48 = add i8 %40, -1
%49 = zext i8 %48 to i64
%50 = getelementptr inbounds i16, i16* %0, i64 %49
%51 = load i16, i16* %50
%52 = icmp eq i16 %51, %2
br i1 %52, label %63, label %59
53: ; preds = %45
%54 = add i8 %40, 1
%55 = zext i8 %54 to i64
%56 = getelementptr inbounds i16, i16* %0, i64 %55
%57 = load i16, i16* %56
%58 = icmp eq i16 %57, %2
br i1 %58, label %63, label %59
59: ; preds = %53, %47
%60 = phi i8 [ %34, %47 ], [ %54, %53 ]
%61 = phi i8 [ %48, %47 ], [ %33, %53 ]
%62 = icmp ugt i8 %61, %60
br i1 %62, label %32, label %63
63: ; preds = %32, %47, %53, %59, %30, %28, %26, %16, %21
%64 = phi i8 [ -1, %21 ], [ -1, %16 ], [ 0, %26 ], [ %18, %28 ], [ -1, %30 ], [ %40, %32 ], [ %48, %47 ], [ %54, %53 ], [ -1, %59 ]
ret i8 %64
}