int mySqrt2(int x) {
  long ans = 0;
  long bit = 1L << 16;
  while (bit) {
    ans |= bit;
    if (ans * ans > x)
      ans ^= bit;
    bit >>= 1;
  }
  return ans;
}


x86 assembly (clang, -O0):
<mySqrt2>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movq   $0x0,-0x10(%rbp)
movq   $0x10000,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     1161 <mySqrt2+0x61>
mov    -0x18(%rbp),%rax
or     -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
imul   -0x10(%rbp),%rax
movslq -0x4(%rbp),%rcx
cmp    %rcx,%rax
jle    1150 <mySqrt2+0x50>
mov    -0x18(%rbp),%rax
xor    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1117 <mySqrt2+0x17>
mov    -0x10(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<mySqrt2>:
movslq %edi,%rcx
xor    %eax,%eax
cmp    $0x40000000,%ecx
setge  %al
mov    %rax,%rdx
shl    $0xf,%rdx
or     $0x4000,%rdx
shl    $0x1f,%rax
or     $0x10000000,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0xe,%rsi
xor    %rdx,%rsi
or     $0x2000,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0xd,%rdx
xor    %rsi,%rdx
or     $0x1000,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0xc,%rsi
xor    %rdx,%rsi
or     $0x800,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0xb,%rdx
xor    %rsi,%rdx
or     $0x400,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0xa,%rsi
xor    %rdx,%rsi
or     $0x200,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0x9,%rdx
xor    %rsi,%rdx
or     $0x100,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0x8,%rsi
xor    %rdx,%rsi
or     $0x80,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0x7,%rdx
xor    %rsi,%rdx
or     $0x40,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0x6,%rsi
xor    %rdx,%rsi
or     $0x20,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0x5,%rdx
xor    %rsi,%rdx
or     $0x10,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0x4,%rsi
xor    %rdx,%rsi
or     $0x8,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
shl    $0x3,%rdx
xor    %rsi,%rdx
or     $0x4,%rdx
mov    %rdx,%rax
imul   %rdx,%rax
xor    %esi,%esi
cmp    %rcx,%rax
setg   %sil
shl    $0x2,%rsi
xor    %rdx,%rsi
or     $0x2,%rsi
mov    %rsi,%rax
imul   %rsi,%rax
xor    %edx,%edx
cmp    %rcx,%rax
setg   %dl
add    %rdx,%rdx
xor    %rsi,%rdx
or     $0x1,%rdx
mov    %rdx,%rsi
imul   %rdx,%rsi
xor    %eax,%eax
cmp    %rcx,%rsi
setg   %al
xor    %edx,%eax
ret

LLVM IR (-O0):
define i32 @mySqrt2(i32 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i64
store i32 %0, i32* %2
store i64 0, i64* %3
store i64 65536, i64* %4
br label %5
5: ; preds = %22, %1
%6 = load i64, i64* %4
%7 = icmp ne i64 %6, 0
br i1 %7, label %8, label %25
8: ; preds = %5
%9 = load i64, i64* %4
%10 = load i64, i64* %3
%11 = or i64 %10, %9
store i64 %11, i64* %3
%12 = load i64, i64* %3
%13 = load i64, i64* %3
%14 = mul nsw i64 %12, %13
%15 = load i32, i32* %2
%16 = sext i32 %15 to i64
%17 = icmp sgt i64 %14, %16
br i1 %17, label %18, label %22
18: ; preds = %8
%19 = load i64, i64* %4
%20 = load i64, i64* %3
%21 = xor i64 %20, %19
store i64 %21, i64* %3
br label %22
22: ; preds = %18, %8
%23 = load i64, i64* %4
%24 = ashr i64 %23, 1
store i64 %24, i64* %4
br label %5
25: ; preds = %5
%26 = load i64, i64* %3
%27 = trunc i64 %26 to i32
ret i32 %27
}

LLVM IR (-O2):
define i32 @mySqrt2(i32 %0) {
%2 = sext i32 %0 to i64
%3 = icmp slt i32 %0, 1073741824
%4 = select i1 %3, i64 16384, i64 49152
%5 = select i1 %3, i64 268435456, i64 2415919104
%6 = icmp sgt i64 %5, %2
%7 = select i1 %6, i64 16384, i64 0
%8 = xor i64 %7, %4
%9 = or i64 %8, 8192
%10 = mul nuw nsw i64 %9, %9
%11 = icmp sgt i64 %10, %2
%12 = select i1 %11, i64 8192, i64 0
%13 = xor i64 %12, %9
%14 = or i64 %13, 4096
%15 = mul nuw nsw i64 %14, %14
%16 = icmp sgt i64 %15, %2
%17 = select i1 %16, i64 4096, i64 0
%18 = xor i64 %17, %14
%19 = or i64 %18, 2048
%20 = mul nsw i64 %19, %19
%21 = icmp sgt i64 %20, %2
%22 = select i1 %21, i64 2048, i64 0
%23 = xor i64 %22, %19
%24 = or i64 %23, 1024
%25 = mul nsw i64 %24, %24
%26 = icmp sgt i64 %25, %2
%27 = select i1 %26, i64 1024, i64 0
%28 = xor i64 %27, %24
%29 = or i64 %28, 512
%30 = mul nsw i64 %29, %29
%31 = icmp sgt i64 %30, %2
%32 = select i1 %31, i64 512, i64 0
%33 = xor i64 %32, %29
%34 = or i64 %33, 256
%35 = mul nsw i64 %34, %34
%36 = icmp sgt i64 %35, %2
%37 = select i1 %36, i64 256, i64 0
%38 = xor i64 %37, %34
%39 = or i64 %38, 128
%40 = mul nsw i64 %39, %39
%41 = icmp sgt i64 %40, %2
%42 = select i1 %41, i64 128, i64 0
%43 = xor i64 %42, %39
%44 = or i64 %43, 64
%45 = mul nsw i64 %44, %44
%46 = icmp sgt i64 %45, %2
%47 = select i1 %46, i64 64, i64 0
%48 = xor i64 %47, %44
%49 = or i64 %48, 32
%50 = mul nsw i64 %49, %49
%51 = icmp sgt i64 %50, %2
%52 = select i1 %51, i64 32, i64 0
%53 = xor i64 %52, %49
%54 = or i64 %53, 16
%55 = mul nsw i64 %54, %54
%56 = icmp sgt i64 %55, %2
%57 = select i1 %56, i64 16, i64 0
%58 = xor i64 %57, %54
%59 = or i64 %58, 8
%60 = mul nsw i64 %59, %59
%61 = icmp sgt i64 %60, %2
%62 = select i1 %61, i64 8, i64 0
%63 = xor i64 %62, %59
%64 = or i64 %63, 4
%65 = mul nsw i64 %64, %64
%66 = icmp sgt i64 %65, %2
%67 = select i1 %66, i64 4, i64 0
%68 = xor i64 %67, %64
%69 = or i64 %68, 2
%70 = mul nsw i64 %69, %69
%71 = icmp sgt i64 %70, %2
%72 = select i1 %71, i64 2, i64 0
%73 = xor i64 %72, %69
%74 = or i64 %73, 1
%75 = mul nsw i64 %74, %74
%76 = icmp sgt i64 %75, %2
%77 = zext i1 %76 to i64
%78 = xor i64 %74, %77
%79 = trunc i64 %78 to i32
ret i32 %79
}