int mp_sqrt_newton(int n, int radix, int in[], int inout[], int inout_rev[],
                   int tmp[], int nfft, double tmp1fft[], double tmp2fft[],
                   int *n_tmp1fft) {
  void mp_round(int n, int radix, int m, int inout[]);
  void mp_add(int n, int radix, int in1[], int in2[], int out[]);
  void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
  void mp_idiv_2(int n, int radix, int in[], int out[]);
  void mp_mulh(int n, int radix, int in1[], int in2[], int out[], int nfft,
               double in1fft[], double outfft[]);
  void mp_squh(int n, int radix, int in[], int out[], int nfft,
               double outfft[]);
  void mp_squh_use_in1fft(int n, int radix, double inoutfft[], int out[],
                          int nfft);
  int n_h, nfft_h, shift, prc;
  nfft_h = nfft >> 1;
  shift = nfft_h + 1;
  if (nfft_h < 2) {
    nfft_h = 2;
  }
  n_h = n / 2 + 1;
  if (n_h < n - shift) {
    n_h = n - shift;
  }
  mp_round(n_h, radix, (nfft_h >> 1) + 1, inout_rev);
  if (*n_tmp1fft != nfft_h) {
    mp_squh(n_h, radix, inout_rev, tmp, nfft_h, tmp1fft);
  } else {
    mp_squh_use_in1fft(n_h, radix, tmp1fft, tmp, nfft_h);
  }
  mp_round(n, radix, shift, inout);
  mp_mulh(n_h, radix, inout, tmp, tmp, nfft, tmp1fft, tmp2fft);
  mp_sub(n_h, radix, inout_rev, tmp, tmp);
  mp_add(n_h, radix, inout_rev, tmp, inout_rev);
  mp_squh_use_in1fft(n, radix, tmp1fft, tmp, nfft);
  mp_sub(n, radix, in, tmp, tmp);
  prc = in[1] - tmp[1];
  if (((short int *)&in[2])[0] > ((short int *)&tmp[2])[0]) {
    prc++;
  }
  if (tmp[0] == 0) {
    prc = nfft + 1;
  }
  mp_round(n_h, radix, shift, inout_rev);
  mp_mulh(n_h, radix, inout_rev, tmp, tmp, nfft, tmp1fft, tmp2fft);
  *n_tmp1fft = nfft;
  mp_idiv_2(n_h, radix, tmp, tmp);
  if (tmp[0] != 0) {
    mp_add(n, radix, inout, tmp, inout);
  }
  return prc;
}


x86 assembly (clang, -O0):
<mp_sqrt_newton>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    0x28(%rbp),%rax
mov    0x20(%rbp),%rax
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%eax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
mov    0x10(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
cmpl   $0x2,-0x30(%rbp)
jge    11c0 <mp_sqrt_newton+0x50>
movl   $0x2,-0x30(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    -0x34(%rbp),%ecx
cmp    %ecx,%eax
jge    11eb <mp_sqrt_newton+0x7b>
mov    -0x4(%rbp),%eax
sub    -0x34(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x30(%rbp),%edx
sar    $0x1,%edx
add    $0x1,%edx
mov    -0x20(%rbp),%rcx
call   1040 <mp_round@plt>
mov    0x28(%rbp),%rax
mov    (%rax),%eax
cmp    -0x30(%rbp),%eax
je     1232 <mp_sqrt_newton+0xc2>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x30(%rbp),%r8d
mov    0x18(%rbp),%r9
call   1060 <mp_squh@plt>
jmp    1249 <mp_sqrt_newton+0xd9>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    0x18(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x30(%rbp),%r8d
call   1090 <mp_squh_use_in1fft@plt>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x34(%rbp),%edx
mov    -0x18(%rbp),%rcx
call   1040 <mp_round@plt>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x28(%rbp),%r8
mov    0x10(%rbp),%r9d
mov    0x18(%rbp),%r10
mov    0x20(%rbp),%rax
mov    %r10,(%rsp)
mov    %rax,0x8(%rsp)
call   1030 <mp_mulh@plt>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x28(%rbp),%r8
call   1070 <mp_sub@plt>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%r8
call   1050 <mp_add@plt>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    0x18(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    0x10(%rbp),%r8d
call   1090 <mp_squh_use_in1fft@plt>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x10(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x28(%rbp),%r8
call   1070 <mp_sub@plt>
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    -0x28(%rbp),%rcx
sub    0x4(%rcx),%eax
mov    %eax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
movswl 0x8(%rax),%eax
mov    -0x28(%rbp),%rcx
movswl 0x8(%rcx),%ecx
cmp    %ecx,%eax
jle    1315 <mp_sqrt_newton+0x1a5>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
mov    -0x28(%rbp),%rax
cmpl   $0x0,(%rax)
jne    132b <mp_sqrt_newton+0x1bb>
mov    0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x34(%rbp),%edx
mov    -0x20(%rbp),%rcx
call   1040 <mp_round@plt>
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x28(%rbp),%r8
mov    0x10(%rbp),%r9d
mov    0x18(%rbp),%r10
mov    0x20(%rbp),%rax
mov    %r10,(%rsp)
mov    %rax,0x8(%rsp)
call   1030 <mp_mulh@plt>
mov    0x10(%rbp),%ecx
mov    0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x2c(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x28(%rbp),%rdx
mov    -0x28(%rbp),%rcx
call   1080 <mp_idiv_2@plt>
mov    -0x28(%rbp),%rax
cmpl   $0x0,(%rax)
je     13a9 <mp_sqrt_newton+0x239>
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x28(%rbp),%rcx
mov    -0x18(%rbp),%r8
call   1050 <mp_add@plt>
mov    -0x38(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mp_sqrt_newton>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    %r9,%rbx
mov    %rcx,0x30(%rsp)
mov    %rdx,0x10(%rsp)
mov    %esi,%r13d
mov    %edi,%r12d
mov    0x88(%rsp),%rbp
mov    0x70(%rsp),%eax
sar    %eax
lea    0x1(%rax),%ecx
cmp    $0x3,%eax
mov    $0x2,%r14d
cmovge %eax,%r14d
mov    %edi,%eax
shr    $0x1f,%eax
add    %edi,%eax
sar    %eax
add    $0x1,%eax
mov    %edi,0xc(%rsp)
mov    %ecx,%r15d
sub    %ecx,%r12d
cmp    %r12d,%eax
cmovge %eax,%r12d
mov    %r14d,%edx
shr    %edx
add    $0x1,%edx
mov    %r12d,%edi
mov    %r8,0x28(%rsp)
mov    %r8,%rcx
call   1040 <mp_round@plt>
cmp    %r14d,0x0(%rbp)
jne    1202 <mp_sqrt_newton+0x92>
mov    %r12d,%edi
mov    %r13d,%esi
mov    0x78(%rsp),%rdx
mov    %rbx,%rcx
mov    %r14d,%r8d
call   1090 <mp_squh_use_in1fft@plt>
jmp    121d <mp_sqrt_newton+0xad>
mov    %r12d,%edi
mov    %r13d,%esi
mov    0x28(%rsp),%rdx
mov    %rbx,%rcx
mov    %r14d,%r8d
mov    0x78(%rsp),%r9
call   1060 <mp_squh@plt>
mov    0xc(%rsp),%edi
mov    %r13d,%esi
mov    %r15d,0x24(%rsp)
mov    %r15d,%edx
mov    0x30(%rsp),%rbp
mov    %rbp,%rcx
call   1040 <mp_round@plt>
mov    %r12d,%edi
mov    %r13d,%esi
mov    %rbp,%rdx
mov    %rbx,%rcx
mov    %rbx,%r8
mov    0x70(%rsp),%r15d
mov    %r15d,%r9d
mov    0x80(%rsp),%rax
push   %rax
mov    0x80(%rsp),%rax
push   %rax
call   1030 <mp_mulh@plt>
add    $0x10,%rsp
mov    %r12d,%edi
mov    %r13d,%esi
mov    0x28(%rsp),%r14
mov    %r14,%rdx
mov    %rbx,%rcx
mov    %rbx,%r8
call   1070 <mp_sub@plt>
mov    %r12d,%edi
mov    %r13d,%esi
mov    %r14,%rdx
mov    %rbx,%rcx
mov    %r14,%r8
call   1050 <mp_add@plt>
mov    0xc(%rsp),%ebp
mov    %ebp,%edi
mov    %r13d,%esi
mov    0x78(%rsp),%rdx
mov    %rbx,%rcx
mov    %r15d,%r8d
call   1090 <mp_squh_use_in1fft@plt>
mov    %ebp,%edi
mov    %r13d,%esi
mov    %r15d,%ebp
mov    0x10(%rsp),%r15
mov    %r15,%rdx
mov    %rbx,%rcx
mov    %rbx,%r8
call   1070 <mp_sub@plt>
mov    0x4(%r15),%eax
mov    %eax,0x1c(%rsp)
mov    (%rbx),%eax
mov    %eax,0x20(%rsp)
mov    0x4(%rbx),%eax
mov    %eax,0x18(%rsp)
movzwl 0x8(%r15),%r15d
movzwl 0x8(%rbx),%eax
mov    %ax,0x10(%rsp)
mov    %r12d,%edi
mov    %r13d,%esi
mov    0x24(%rsp),%edx
mov    %r14,%rcx
call   1040 <mp_round@plt>
mov    %r12d,%edi
mov    %r13d,%esi
mov    %r14,%rdx
mov    %rbx,%rcx
mov    %rbx,%r8
mov    %ebp,%r9d
push   0x80(%rsp)
push   0x80(%rsp)
call   1030 <mp_mulh@plt>
add    $0x10,%rsp
mov    0x88(%rsp),%rax
mov    %ebp,(%rax)
mov    %r12d,%edi
mov    %r13d,%r14d
mov    %r13d,%esi
mov    %rbx,%rdx
mov    %rbx,%rcx
call   1080 <mp_idiv_2@plt>
cmpl   $0x0,(%rbx)
je     1364 <mp_sqrt_newton+0x1f4>
mov    0xc(%rsp),%edi
mov    %r14d,%esi
mov    0x30(%rsp),%rdx
mov    %rbx,%rcx
mov    %rdx,%r8
call   1050 <mp_add@plt>
add    $0x1,%ebp
mov    0x1c(%rsp),%ecx
sub    0x18(%rsp),%ecx
xor    %eax,%eax
cmp    0x10(%rsp),%r15w
setg   %al
add    %ecx,%eax
cmpl   $0x0,0x20(%rsp)
cmove  %ebp,%eax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i32 @mp_sqrt_newton(i32 %0, i32 %1, i32* %2, i32* %3, i32* %4, i32* %5, i32 %6, double* %7, double* %8, i32* nocapture %9) {
%11 = ashr i32 %6, 1
%12 = add nsw i32 %11, 1
%13 = icmp sgt i32 %11, 2
%14 = select i1 %13, i32 %11, i32 2
%15 = sdiv i32 %0, 2
%16 = add nsw i32 %15, 1
%17 = sub nsw i32 %0, %12
%18 = icmp slt i32 %16, %17
%19 = select i1 %18, i32 %17, i32 %16
%20 = lshr i32 %14, 1
%21 = add nuw nsw i32 %20, 1
tail call void @mp_round(i32 %19, i32 %1, i32 %21, i32* %4)
%22 = load i32, i32* %9
%23 = icmp eq i32 %22, %14
br i1 %23, label %25, label %24
24: ; preds = %10
tail call void @mp_squh(i32 %19, i32 %1, i32* %4, i32* %5, i32 %14, double* %7)
br label %26
25: ; preds = %10
tail call void @mp_squh_use_in1fft(i32 %19, i32 %1, double* %7, i32* %5, i32 %14)
br label %26
26: ; preds = %25, %24
tail call void @mp_round(i32 %0, i32 %1, i32 %12, i32* %3)
tail call void @mp_mulh(i32 %19, i32 %1, i32* %3, i32* %5, i32* %5, i32 %6, double* %7, double* %8)
tail call void @mp_sub(i32 %19, i32 %1, i32* %4, i32* %5, i32* %5)
tail call void @mp_add(i32 %19, i32 %1, i32* %4, i32* %5, i32* %4)
tail call void @mp_squh_use_in1fft(i32 %0, i32 %1, double* %7, i32* %5, i32 %6)
tail call void @mp_sub(i32 %0, i32 %1, i32* %2, i32* %5, i32* %5)
%27 = getelementptr inbounds i32, i32* %2, i64 1
%28 = load i32, i32* %27
%29 = getelementptr inbounds i32, i32* %5, i64 1
%30 = load i32, i32* %29
%31 = getelementptr inbounds i32, i32* %2, i64 2
%32 = bitcast i32* %31 to i16*
%33 = load i16, i16* %32
%34 = getelementptr inbounds i32, i32* %5, i64 2
%35 = bitcast i32* %34 to i16*
%36 = load i16, i16* %35
%37 = load i32, i32* %5
tail call void @mp_round(i32 %19, i32 %1, i32 %12, i32* %4)
tail call void @mp_mulh(i32 %19, i32 %1, i32* %4, i32* %5, i32* %5, i32 %6, double* %7, double* %8)
store i32 %6, i32* %9
tail call void @mp_idiv_2(i32 %19, i32 %1, i32* %5, i32* %5)
%38 = load i32, i32* %5
%39 = icmp eq i32 %38, 0
br i1 %39, label %41, label %40
40: ; preds = %26
tail call void @mp_add(i32 %0, i32 %1, i32* %3, i32* %5, i32* %3)
br label %41
41: ; preds = %40, %26
%42 = icmp eq i32 %37, 0
%43 = add nsw i32 %6, 1
%44 = sub i32 %28, %30
%45 = icmp sgt i16 %33, %36
%46 = zext i1 %45 to i32
%47 = add nsw i32 %44, %46
%48 = select i1 %42, i32 %43, i32 %47
ret i32 %48
}