#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 */

/* Variables and functions */
int /*<<< orphan*/ printf(char *, ...);
int main(int argc, char **argv) {
  int x, y, z, N, f;
  printf("#define TFM_DEFINES\n"
         "#include \"fp_sqr_comba.c\"\n"
         "\n"
         "#if defined(TFM_SMALL_SET)\n"
         "void fp_sqr_comba_small(fp_int *A, fp_int *B)\n"
         "{\n"
         "   fp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;\n"
         "#ifdef TFM_ISO\n"
         "   fp_word tt;\n"
         "#endif\n");
  printf("   switch (A->used) { \n");
  for (N = 1; N <= 16; N++) {
    printf("   case %d:\n"
           "      a = A->dp;\n"
           "      COMBA_START; \n"
           "\n"
           "      /* clear carries */\n"
           "      CLEAR_CARRY;\n"
           "\n"
           "      /* output 0 */\n"
           "      SQRADD(a[0],a[0]);\n"
           "      COMBA_STORE(b[0]);\n",
           N);
    for (x = 1; x < N + N - 1; x++) {
      printf("\n      /* output %d */\n"
             "      CARRY_FORWARD;\n   ",
             x);
      for (f = y = 0; y < N; y++) {
        for (z = 0; z < N; z++) {
          if (z != y && z + y == x && y <= z) {
            ++f;
          }
        }
      }
      if (f <= 2) {
        for (y = 0; y < N; y++) {
          for (z = 0; z < N; z++) {
            if (y <= z && (y + z) == x) {
              if (y == z) {
                printf("   SQRADD(a[%d], a[%d]); ", y, y);
              } else {
                printf("   SQRADD2(a[%d], a[%d]); ", y, z);
              }
            }
          }
        }
      } else {
        f = 0;
        for (y = 0; y < N; y++) {
          for (z = 0; z < N; z++) {
            if (z != y && z + y == x && y <= z) {
              if (f == 0) {
                printf("SQRADDSC(a[%d], a[%d]); ", y, z);
                f = 1;
              } else {
                printf("SQRADDAC(a[%d], a[%d]); ", y, z);
              }
            }
          }
        }
        printf("SQRADDDB; ");
        if ((x & 1) == 0) {
          printf("SQRADD(a[%d], a[%d]); ", x / 2, x / 2);
        }
      }
      printf("\n      COMBA_STORE(b[%d]);\n", x);
    }
    printf("      COMBA_STORE2(b[%d]);\n", N + N - 1);
    printf("      COMBA_FINI;\n"
           "\n"
           "      B->used = %d;\n"
           "      B->sign = FP_ZPOS;\n"
           "      memcpy(B->dp, b, %d * sizeof(fp_digit));\n"
           "      memset(B->dp + %d, 0, (FP_SIZE - %d) * sizeof(fp_digit));\n"
           "      fp_clamp(B);\n"
           "      break;\n\n",
           N + N, N + N, N + N, N + N);
  }
  printf("}\n}\n\n#endif /* TFM_SMALL_SET */\n");
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    0xed3(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xf97(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x1,-0x20(%rbp)
cmpl   $0x10,-0x20(%rbp)
jg     143a <main+0x32a>
mov    -0x20(%rbp),%esi
lea    0xf8d(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x1,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    -0x20(%rbp),%ecx
add    -0x20(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    13ed <main+0x2dd>
mov    -0x14(%rbp),%esi
lea    0x1009(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1213 <main+0x103>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1200 <main+0xf0>
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
je     11ed <main+0xdd>
mov    -0x1c(%rbp),%eax
add    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jne    11ed <main+0xdd>
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     11ed <main+0xdd>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11f2 <main+0xe2>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11b1 <main+0xa1>
jmp    1205 <main+0xf5>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    119e <main+0x8e>
cmpl   $0x2,-0x24(%rbp)
jg     12c7 <main+0x1b7>
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    12c2 <main+0x1b2>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    12af <main+0x19f>
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     129c <main+0x18c>
mov    -0x18(%rbp),%eax
add    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jne    129c <main+0x18c>
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jne    1283 <main+0x173>
mov    -0x18(%rbp),%esi
mov    -0x18(%rbp),%edx
lea    0xf4b(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    1297 <main+0x187>
mov    -0x18(%rbp),%esi
mov    -0x1c(%rbp),%edx
lea    0xf4c(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    129c <main+0x18c>
jmp    12a1 <main+0x191>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1237 <main+0x127>
jmp    12b4 <main+0x1a4>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1224 <main+0x114>
jmp    13ce <main+0x2be>
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1384 <main+0x274>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1371 <main+0x261>
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
je     135e <main+0x24e>
mov    -0x1c(%rbp),%eax
add    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jne    135e <main+0x24e>
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     135e <main+0x24e>
cmpl   $0x0,-0x24(%rbp)
jne    1345 <main+0x235>
mov    -0x18(%rbp),%esi
mov    -0x1c(%rbp),%edx
lea    0xec5(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x1,-0x24(%rbp)
jmp    1359 <main+0x249>
mov    -0x18(%rbp),%esi
mov    -0x1c(%rbp),%edx
lea    0xebe(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    135e <main+0x24e>
jmp    1363 <main+0x253>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    12e8 <main+0x1d8>
jmp    1376 <main+0x266>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    12d5 <main+0x1c5>
lea    0xe9e(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x14(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
jne    13c9 <main+0x2b9>
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%esi
mov    -0x14(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%edx
lea    0xe03(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    13ce <main+0x2be>
mov    -0x14(%rbp),%esi
lea    0xe5c(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    116b <main+0x5b>
mov    -0x20(%rbp),%esi
add    -0x20(%rbp),%esi
sub    $0x1,%esi
lea    0xe53(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x20(%rbp),%esi
add    -0x20(%rbp),%esi
mov    -0x20(%rbp),%edx
add    -0x20(%rbp),%edx
mov    -0x20(%rbp),%ecx
add    -0x20(%rbp),%ecx
mov    -0x20(%rbp),%r8d
add    -0x20(%rbp),%r8d
lea    0xe47(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1149 <main+0x39>
lea    0xefc(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
xor    %eax,%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
lea    0x116e(%rip),%rdi
call   1030 <puts@plt>
lea    0x1233(%rip),%rdi
call   1030 <puts@plt>
mov    $0x1,%eax
lea    0x100b(%rip),%r12
lea    0x101d(%rip),%r13
mov    $0x1,%r14d
jmp    11b3 <main+0x93>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    (%r14,%r14,1),%esi
add    $0xffffffff,%esi
lea    0x1038(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0x1046(%rip),%rdi
mov    0x8(%rsp),%ecx
mov    %ecx,%esi
mov    %ecx,%edx
mov    %ecx,%r8d
xor    %eax,%eax
call   1040 <printf@plt>
add    $0x1,%r14d
mov    0xc(%rsp),%eax
add    $0x2,%eax
cmp    $0x11,%r14d
je     1524 <main+0x404>
cmp    $0x3,%eax
mov    $0x2,%ecx
mov    %eax,0xc(%rsp)
cmovge %eax,%ecx
mov    %ecx,0x14(%rsp)
lea    0xe83(%rip),%rdi
mov    %r14d,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    (%r14,%r14,1),%eax
mov    %eax,0x8(%rsp)
cmp    $0x2,%r14d
jb     1170 <main+0x50>
mov    %r14d,%r15d
and    $0xfffffffc,%r15d
add    $0xfffffffc,%r15d
shr    $0x2,%r15d
add    $0x1,%r15d
and    $0xfffffffe,%r15d
mov    %r14d,%eax
and    $0x7ffffffc,%eax
mov    %rax,0x20(%rsp)
add    $0xfffffffc,%eax
mov    %eax,0x1c(%rsp)
shr    $0x2,%eax
add    $0x1,%eax
mov    %eax,0x18(%rsp)
mov    $0x1,%ebx
mov    %r15d,0x10(%rsp)
jmp    1256 <main+0x136>
cs nopw 0x0(%rax,%rax,1)
lea    0xf63(%rip),%rdi
mov    0x4(%rsp),%ebx
mov    %ebx,%esi
xor    %eax,%eax
call   1040 <printf@plt>
add    $0x1,%ebx
cmp    0x14(%rsp),%ebx
mov    0x10(%rsp),%r15d
je     1170 <main+0x50>
xor    %ebp,%ebp
lea    0xe99(%rip),%rdi
mov    %ebx,%esi
xor    %eax,%eax
call   1040 <printf@plt>
movd   %ebx,%xmm0
pshufd $0x0,%xmm0,%xmm8
mov    %ebx,0x4(%rsp)
mov    %ebx,%esi
xor    %edi,%edi
pcmpeqd %xmm9,%xmm9
movdqa 0xd88(%rip),%xmm10
movdqa 0xd8f(%rip),%xmm11
movdqa 0xd96(%rip),%xmm12
movdqa 0xd9d(%rip),%xmm13
jmp    12bf <main+0x19f>
cs nopw 0x0(%rax,%rax,1)
nop
add    $0x1,%edi
add    $0xffffffff,%esi
cmp    %r14d,%edi
je     1430 <main+0x310>
cmp    $0x4,%r14d
jae    12d0 <main+0x1b0>
xor    %edx,%edx
jmp    13f0 <main+0x2d0>
nopl   0x0(%rax)
movd   %ebp,%xmm3
movd   %edi,%xmm1
pshufd $0x0,%xmm1,%xmm2
movdqa %xmm2,%xmm1
pxor   %xmm10,%xmm1
cmpl   $0x0,0x1c(%rsp)
je     1413 <main+0x2f3>
mov    %r15d,%edx
movdqa 0xd04(%rip),%xmm4
nopl   0x0(%rax)
movdqa %xmm4,%xmm5
pcmpeqd %xmm2,%xmm5
movdqa %xmm4,%xmm6
paddd  %xmm2,%xmm6
pcmpeqd %xmm8,%xmm6
pxor   %xmm9,%xmm6
por    %xmm5,%xmm6
movdqa %xmm4,%xmm5
pxor   %xmm10,%xmm5
movdqa %xmm1,%xmm7
pcmpgtd %xmm5,%xmm7
por    %xmm6,%xmm7
paddd  %xmm3,%xmm7
movdqa %xmm4,%xmm5
paddd  %xmm11,%xmm5
movdqa %xmm5,%xmm6
pcmpeqd %xmm2,%xmm6
movdqa %xmm5,%xmm0
paddd  %xmm2,%xmm0
pcmpeqd %xmm8,%xmm0
pxor   %xmm9,%xmm0
pxor   %xmm10,%xmm5
movdqa %xmm1,%xmm3
pcmpgtd %xmm5,%xmm3
por    %xmm6,%xmm3
por    %xmm0,%xmm3
paddd  %xmm7,%xmm3
paddd  %xmm12,%xmm3
paddd  %xmm13,%xmm4
add    $0xfffffffe,%edx
jne    1300 <main+0x1e0>
testb  $0x1,0x18(%rsp)
je     13bd <main+0x29d>
movdqa %xmm4,%xmm0
pcmpeqd %xmm2,%xmm0
paddd  %xmm4,%xmm2
pcmpeqd %xmm8,%xmm2
pxor   %xmm9,%xmm2
pxor   %xmm10,%xmm4
pcmpgtd %xmm4,%xmm1
por    %xmm0,%xmm1
por    %xmm2,%xmm1
paddd  %xmm1,%xmm3
psubd  %xmm9,%xmm3
pshufd $0xee,%xmm3,%xmm0
paddd  %xmm3,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%ebp
mov    0x20(%rsp),%rax
mov    %eax,%edx
cmp    %eax,%r14d
je     12b0 <main+0x190>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
cmp    %edx,%esi
sete   %al
cmp    %edx,%edi
setne  %cl
setbe  %bl
and    %al,%cl
and    %bl,%cl
movzbl %cl,%eax
add    %eax,%ebp
add    $0x1,%edx
cmp    %edx,%r14d
jne    13f0 <main+0x2d0>
jmp    12b0 <main+0x190>
movdqa 0xbe5(%rip),%xmm4
testb  $0x1,0x18(%rsp)
jne    138d <main+0x26d>
jmp    13bd <main+0x29d>
nopl   0x0(%rax,%rax,1)
cmp    $0x3,%ebp
jge    14a0 <main+0x380>
xor    %ebp,%ebp
mov    0x4(%rsp),%r15d
jmp    1450 <main+0x330>
xchg   %ax,%ax
add    $0x1,%ebp
add    $0xffffffff,%r15d
cmp    %r14d,%ebp
je     1230 <main+0x110>
xor    %ebx,%ebx
jmp    147a <main+0x35a>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    0xcdb(%rip),%rdi
mov    %ebp,%esi
mov    %ebx,%edx
xor    %eax,%eax
call   1040 <printf@plt>
add    $0x1,%ebx
cmp    %ebx,%r14d
je     1440 <main+0x320>
cmp    %ebx,%ebp
ja     1472 <main+0x352>
cmp    %ebx,%r15d
jne    1472 <main+0x352>
cmp    %ebx,%ebp
jne    1460 <main+0x340>
lea    0xc9a(%rip),%rdi
mov    %ebp,%esi
mov    %ebp,%edx
jmp    146b <main+0x34b>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
xor    %eax,%eax
mov    0x4(%rsp),%ebx
xor    %r15d,%r15d
jmp    14bc <main+0x39c>
nopl   0x0(%rax,%rax,1)
add    $0x1,%r15d
add    $0xffffffff,%ebx
cmp    %r14d,%r15d
je     14f0 <main+0x3d0>
xor    %ebp,%ebp
jmp    14c8 <main+0x3a8>
add    $0x1,%ebp
cmp    %ebp,%r14d
je     14b0 <main+0x390>
cmp    %ebp,%r15d
ja     14c0 <main+0x3a0>
je     14c0 <main+0x3a0>
cmp    %ebp,%ebx
jne    14c0 <main+0x3a0>
test   %eax,%eax
mov    %r13,%rdi
cmove  %r12,%rdi
mov    %r15d,%esi
mov    %ebp,%edx
xor    %eax,%eax
call   1040 <printf@plt>
mov    $0x1,%eax
jmp    14c0 <main+0x3a0>
nop
lea    0xc98(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
testb  $0x1,0x4(%rsp)
jne    1230 <main+0x110>
mov    0x4(%rsp),%edx
shr    %edx
lea    0xc15(%rip),%rdi
mov    %edx,%esi
xor    %eax,%eax
call   1040 <printf@plt>
jmp    1230 <main+0x110>
lea    0xe60(%rip),%rdi
call   1030 <puts@plt>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [210 x i8] c"#define TFM_DEFINES\0A#include \22fp_sqr_comba.c\22\0A\0A#if defined(TFM_SMALL_SET)\0Avoid fp_sqr_comba_small(fp_int *A, fp_int *B)\0A{\0A fp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;\0A#ifdef TFM_ISO\0A fp_word tt;\0A#endif\0A\00"
@.str.1 = [24 x i8] c" switch (A->used) { \0A\00"
@.str.2 = [168 x i8] c" case %d:\0A a = A->dp;\0A COMBA_START; \0A\0A /* clear carries */\0A CLEAR_CARRY;\0A\0A /* output 0 */\0A SQRADD(a[0],a[0]);\0A COMBA_STORE(b[0]);\0A\00"
@.str.3 = [48 x i8] c"\0A /* output %d */\0A CARRY_FORWARD;\0A \00"
@.str.4 = [26 x i8] c" SQRADD(a[%d], a[%d]); \00"
@.str.5 = [27 x i8] c" SQRADD2(a[%d], a[%d]); \00"
@.str.6 = [25 x i8] c"SQRADDSC(a[%d], a[%d]); \00"
@.str.7 = [25 x i8] c"SQRADDAC(a[%d], a[%d]); \00"
@.str.8 = [11 x i8] c"SQRADDDB; \00"
@.str.9 = [23 x i8] c"SQRADD(a[%d], a[%d]); \00"
@.str.10 = [28 x i8] c"\0A COMBA_STORE(b[%d]);\0A\00"
@.str.11 = [28 x i8] c" COMBA_STORE2(b[%d]);\0A\00"
@.str.12 = [209 x i8] c" COMBA_FINI;\0A\0A B->used = %d;\0A B->sign = FP_ZPOS;\0A memcpy(B->dp, b, %d * sizeof(fp_digit));\0A memset(B->dp + %d, 0, (FP_SIZE - %d) * sizeof(fp_digit));\0A fp_clamp(B);\0A break;\0A\0A\00"
@.str.13 = [33 x i8] c"}\0A}\0A\0A#endif /* TFM_SMALL_SET */\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([210 x i8], [210 x i8]* @.str, i64 0, i64 0))
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.1, i64 0, i64 0))
store i32 1, i32* %9
br label %13
13: ; preds = %189, %2
%14 = load i32, i32* %9
%15 = icmp sle i32 %14, 16
br i1 %15, label %16, label %192
16: ; preds = %13
%17 = load i32, i32* %9
%18 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([168 x i8], [168 x i8]* @.str.2, i64 0, i64 0), i32 %17)
store i32 1, i32* %6
br label %19
19: ; preds = %167, %16
%20 = load i32, i32* %6
%21 = load i32, i32* %9
%22 = load i32, i32* %9
%23 = add nsw i32 %21, %22
%24 = sub nsw i32 %23, 1
%25 = icmp slt i32 %20, %24
br i1 %25, label %26, label %170
26: ; preds = %19
%27 = load i32, i32* %6
%28 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([48 x i8], [48 x i8]* @.str.3, i64 0, i64 0), i32 %27)
store i32 0, i32* %7
store i32 0, i32* %10
br label %29
29: ; preds = %60, %26
%30 = load i32, i32* %7
%31 = load i32, i32* %9
%32 = icmp slt i32 %30, %31
br i1 %32, label %33, label %63
33: ; preds = %29
store i32 0, i32* %8
br label %34
34: ; preds = %56, %33
%35 = load i32, i32* %8
%36 = load i32, i32* %9
%37 = icmp slt i32 %35, %36
br i1 %37, label %38, label %59
38: ; preds = %34
%39 = load i32, i32* %8
%40 = load i32, i32* %7
%41 = icmp ne i32 %39, %40
br i1 %41, label %42, label %55
42: ; preds = %38
%43 = load i32, i32* %8
%44 = load i32, i32* %7
%45 = add nsw i32 %43, %44
%46 = load i32, i32* %6
%47 = icmp eq i32 %45, %46
br i1 %47, label %48, label %55
48: ; preds = %42
%49 = load i32, i32* %7
%50 = load i32, i32* %8
%51 = icmp sle i32 %49, %50
br i1 %51, label %52, label %55
52: ; preds = %48
%53 = load i32, i32* %10
%54 = add nsw i32 %53, 1
store i32 %54, i32* %10
br label %55
55: ; preds = %52, %48, %42, %38
br label %56
56: ; preds = %55
%57 = load i32, i32* %8
%58 = add nsw i32 %57, 1
store i32 %58, i32* %8
br label %34
59: ; preds = %34
br label %60
60: ; preds = %59
%61 = load i32, i32* %7
%62 = add nsw i32 %61, 1
store i32 %62, i32* %7
br label %29
63: ; preds = %29
%64 = load i32, i32* %10
%65 = icmp sle i32 %64, 2
br i1 %65, label %66, label %108
66: ; preds = %63
store i32 0, i32* %7
br label %67
67: ; preds = %104, %66
%68 = load i32, i32* %7
%69 = load i32, i32* %9
%70 = icmp slt i32 %68, %69
br i1 %70, label %71, label %107
71: ; preds = %67
store i32 0, i32* %8
br label %72
72: ; preds = %100, %71
%73 = load i32, i32* %8
%74 = load i32, i32* %9
%75 = icmp slt i32 %73, %74
br i1 %75, label %76, label %103
76: ; preds = %72
%77 = load i32, i32* %7
%78 = load i32, i32* %8
%79 = icmp sle i32 %77, %78
br i1 %79, label %80, label %99
80: ; preds = %76
%81 = load i32, i32* %7
%82 = load i32, i32* %8
%83 = add nsw i32 %81, %82
%84 = load i32, i32* %6
%85 = icmp eq i32 %83, %84
br i1 %85, label %86, label %99
86: ; preds = %80
%87 = load i32, i32* %7
%88 = load i32, i32* %8
%89 = icmp eq i32 %87, %88
br i1 %89, label %90, label %94
90: ; preds = %86
%91 = load i32, i32* %7
%92 = load i32, i32* %7
%93 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.4, i64 0, i64 0), i32 %91, i32 %92)
br label %98
94: ; preds = %86
%95 = load i32, i32* %7
%96 = load i32, i32* %8
%97 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.5, i64 0, i64 0), i32 %95, i32 %96)
br label %98
98: ; preds = %94, %90
br label %99
99: ; preds = %98, %80, %76
br label %100
100: ; preds = %99
%101 = load i32, i32* %8
%102 = add nsw i32 %101, 1
store i32 %102, i32* %8
br label %72
103: ; preds = %72
br label %104
104: ; preds = %103
%105 = load i32, i32* %7
%106 = add nsw i32 %105, 1
store i32 %106, i32* %7
br label %67
107: ; preds = %67
br label %164
108: ; preds = %63
store i32 0, i32* %10
store i32 0, i32* %7
br label %109
109: ; preds = %149, %108
%110 = load i32, i32* %7
%111 = load i32, i32* %9
%112 = icmp slt i32 %110, %111
br i1 %112, label %113, label %152
113: ; preds = %109
store i32 0, i32* %8
br label %114
114: ; preds = %145, %113
%115 = load i32, i32* %8
%116 = load i32, i32* %9
%117 = icmp slt i32 %115, %116
br i1 %117, label %118, label %148
118: ; preds = %114
%119 = load i32, i32* %8
%120 = load i32, i32* %7
%121 = icmp ne i32 %119, %120
br i1 %121, label %122, label %144
122: ; preds = %118
%123 = load i32, i32* %8
%124 = load i32, i32* %7
%125 = add nsw i32 %123, %124
%126 = load i32, i32* %6
%127 = icmp eq i32 %125, %126
br i1 %127, label %128, label %144
128: ; preds = %122
%129 = load i32, i32* %7
%130 = load i32, i32* %8
%131 = icmp sle i32 %129, %130
br i1 %131, label %132, label %144
132: ; preds = %128
%133 = load i32, i32* %10
%134 = icmp eq i32 %133, 0
br i1 %134, label %135, label %139
135: ; preds = %132
%136 = load i32, i32* %7
%137 = load i32, i32* %8
%138 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.6, i64 0, i64 0), i32 %136, i32 %137)
store i32 1, i32* %10
br label %143
139: ; preds = %132
%140 = load i32, i32* %7
%141 = load i32, i32* %8
%142 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.7, i64 0, i64 0), i32 %140, i32 %141)
br label %143
143: ; preds = %139, %135
br label %144
144: ; preds = %143, %128, %122, %118
br label %145
145: ; preds = %144
%146 = load i32, i32* %8
%147 = add nsw i32 %146, 1
store i32 %147, i32* %8
br label %114
148: ; preds = %114
br label %149
149: ; preds = %148
%150 = load i32, i32* %7
%151 = add nsw i32 %150, 1
store i32 %151, i32* %7
br label %109
152: ; preds = %109
%153 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.8, i64 0, i64 0))
%154 = load i32, i32* %6
%155 = and i32 %154, 1
%156 = icmp eq i32 %155, 0
br i1 %156, label %157, label %163
157: ; preds = %152
%158 = load i32, i32* %6
%159 = sdiv i32 %158, 2
%160 = load i32, i32* %6
%161 = sdiv i32 %160, 2
%162 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.9, i64 0, i64 0), i32 %159, i32 %161)
br label %163
163: ; preds = %157, %152
br label %164
164: ; preds = %163, %107
%165 = load i32, i32* %6
%166 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.10, i64 0, i64 0), i32 %165)
br label %167
167: ; preds = %164
%168 = load i32, i32* %6
%169 = add nsw i32 %168, 1
store i32 %169, i32* %6
br label %19
170: ; preds = %19
%171 = load i32, i32* %9
%172 = load i32, i32* %9
%173 = add nsw i32 %171, %172
%174 = sub nsw i32 %173, 1
%175 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.11, i64 0, i64 0), i32 %174)
%176 = load i32, i32* %9
%177 = load i32, i32* %9
%178 = add nsw i32 %176, %177
%179 = load i32, i32* %9
%180 = load i32, i32* %9
%181 = add nsw i32 %179, %180
%182 = load i32, i32* %9
%183 = load i32, i32* %9
%184 = add nsw i32 %182, %183
%185 = load i32, i32* %9
%186 = load i32, i32* %9
%187 = add nsw i32 %185, %186
%188 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([209 x i8], [209 x i8]* @.str.12, i64 0, i64 0), i32 %178, i32 %181, i32 %184, i32 %187)
br label %189
189: ; preds = %170
%190 = load i32, i32* %9
%191 = add nsw i32 %190, 1
store i32 %191, i32* %9
br label %13
192: ; preds = %13
%193 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.13, i64 0, i64 0))
ret i32 0
}

LLVM IR (-O2):
@.str.2 = [168 x i8] c" case %d:\0A a = A->dp;\0A COMBA_START; \0A\0A /* clear carries */\0A CLEAR_CARRY;\0A\0A /* output 0 */\0A SQRADD(a[0],a[0]);\0A COMBA_STORE(b[0]);\0A\00"
@.str.3 = [48 x i8] c"\0A /* output %d */\0A CARRY_FORWARD;\0A \00"
@.str.4 = [26 x i8] c" SQRADD(a[%d], a[%d]); \00"
@.str.5 = [27 x i8] c" SQRADD2(a[%d], a[%d]); \00"
@.str.6 = [25 x i8] c"SQRADDSC(a[%d], a[%d]); \00"
@.str.7 = [25 x i8] c"SQRADDAC(a[%d], a[%d]); \00"
@.str.8 = [11 x i8] c"SQRADDDB; \00"
@.str.9 = [23 x i8] c"SQRADD(a[%d], a[%d]); \00"
@.str.10 = [28 x i8] c"\0A COMBA_STORE(b[%d]);\0A\00"
@.str.11 = [28 x i8] c" COMBA_STORE2(b[%d]);\0A\00"
@.str.12 = [209 x i8] c" COMBA_FINI;\0A\0A B->used = %d;\0A B->sign = FP_ZPOS;\0A memcpy(B->dp, b, %d * sizeof(fp_digit));\0A memset(B->dp + %d, 0, (FP_SIZE - %d) * sizeof(fp_digit));\0A fp_clamp(B);\0A break;\0A\0A\00"
@str = [209 x i8] c"#define TFM_DEFINES\0A#include \22fp_sqr_comba.c\22\0A\0A#if defined(TFM_SMALL_SET)\0Avoid fp_sqr_comba_small(fp_int *A, fp_int *B)\0A{\0A fp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;\0A#ifdef TFM_ISO\0A fp_word tt;\0A#endif\00"
@str.14 = [23 x i8] c" switch (A->used) { \00"
@str.15 = [32 x i8] c"}\0A}\0A\0A#endif /* TFM_SMALL_SET */\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([209 x i8], [209 x i8]* @str, i64 0, i64 0))
%4 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @str.14, i64 0, i64 0))
br label %5
5: ; preds = %2, %157
%6 = phi i32 [ 1, %2 ], [ %161, %157 ]
%7 = phi i32 [ 1, %2 ], [ %160, %157 ]
%8 = and i32 %7, 2147483644
%9 = add nsw i32 %8, -4
%10 = lshr exact i32 %9, 2
%11 = add nuw nsw i32 %10, 1
%12 = call i32 @llvm.smax.i32(i32 %6, i32 2)
%13 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([168 x i8], [168 x i8]* @.str.2, i64 0, i64 0), i32 %7)
%14 = shl nuw nsw i32 %7, 1
%15 = add nsw i32 %14, -1
%16 = icmp ugt i32 %7, 1
br i1 %16, label %17, label %157
17: ; preds = %5
%18 = icmp ult i32 %7, 4
%19 = and i32 %7, 2147483644
%20 = and i32 %11, 1
%21 = icmp eq i32 %9, 0
%22 = and i32 %11, 2147483646
%23 = icmp eq i32 %20, 0
%24 = icmp eq i32 %7, %19
br label %25
25: ; preds = %17, %153
%26 = phi i32 [ %155, %153 ], [ 1, %17 ]
%27 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([48 x i8], [48 x i8]* @.str.3, i64 0, i64 0), i32 %26)
%28 = insertelement <4 x i32> poison, i32 %26, i64 0
%29 = shufflevector <4 x i32> %28, <4 x i32> poison, <4 x i32> zeroinitializer
br label %30
30: ; preds = %25, %97
%31 = phi i32 [ 0, %25 ], [ %98, %97 ]
%32 = phi i32 [ 0, %25 ], [ %99, %97 ]
br i1 %18, label %80, label %33
33: ; preds = %30
%34 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %31, i64 0
%35 = insertelement <4 x i32> poison, i32 %32, i64 0
%36 = shufflevector <4 x i32> %35, <4 x i32> poison, <4 x i32> zeroinitializer
br i1 %21, label %63, label %37
37: ; preds = %33, %37
%38 = phi <4 x i32> [ %59, %37 ], [ %34, %33 ]
%39 = phi <4 x i32> [ %60, %37 ], [ <i32 0, i32 1, i32 2, i32 3>, %33 ]
%40 = phi i32 [ %61, %37 ], [ 0, %33 ]
%41 = icmp eq <4 x i32> %39, %36
%42 = add nuw nsw <4 x i32> %39, %36
%43 = icmp ne <4 x i32> %42, %29
%44 = select <4 x i1> %41, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> %43
%45 = icmp ugt <4 x i32> %36, %39
%46 = or <4 x i1> %45, %44
%47 = xor <4 x i1> %46, <i1 true, i1 true, i1 true, i1 true>
%48 = zext <4 x i1> %47 to <4 x i32>
%49 = add <4 x i32> %38, %48
%50 = add <4 x i32> %39, <i32 4, i32 4, i32 4, i32 4>
%51 = icmp eq <4 x i32> %50, %36
%52 = add nuw nsw <4 x i32> %50, %36
%53 = icmp ne <4 x i32> %52, %29
%54 = select <4 x i1> %51, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> %53
%55 = icmp ugt <4 x i32> %36, %50
%56 = or <4 x i1> %55, %54
%57 = xor <4 x i1> %56, <i1 true, i1 true, i1 true, i1 true>
%58 = zext <4 x i1> %57 to <4 x i32>
%59 = add <4 x i32> %49, %58
%60 = add <4 x i32> %39, <i32 8, i32 8, i32 8, i32 8>
%61 = add i32 %40, 2
%62 = icmp eq i32 %61, %22
br i1 %62, label %63, label %37
63: ; preds = %37, %33
%64 = phi <4 x i32> [ undef, %33 ], [ %59, %37 ]
%65 = phi <4 x i32> [ %34, %33 ], [ %59, %37 ]
%66 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %33 ], [ %60, %37 ]
br i1 %23, label %77, label %67
67: ; preds = %63
%68 = icmp eq <4 x i32> %66, %36
%69 = add nuw nsw <4 x i32> %66, %36
%70 = icmp ne <4 x i32> %69, %29
%71 = select <4 x i1> %68, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i1> %70
%72 = icmp ugt <4 x i32> %36, %66
%73 = or <4 x i1> %72, %71
%74 = xor <4 x i1> %73, <i1 true, i1 true, i1 true, i1 true>
%75 = zext <4 x i1> %74 to <4 x i32>
%76 = add <4 x i32> %65, %75
br label %77
77: ; preds = %63, %67
%78 = phi <4 x i32> [ %64, %63 ], [ %76, %67 ]
%79 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %78)
br i1 %24, label %97, label %80
80: ; preds = %30, %77
%81 = phi i32 [ %31, %30 ], [ %79, %77 ]
%82 = phi i32 [ 0, %30 ], [ %19, %77 ]
br label %83
83: ; preds = %80, %83
%84 = phi i32 [ %94, %83 ], [ %81, %80 ]
%85 = phi i32 [ %95, %83 ], [ %82, %80 ]
%86 = icmp eq i32 %85, %32
%87 = add nuw nsw i32 %85, %32
%88 = icmp ne i32 %87, %26
%89 = select i1 %86, i1 true, i1 %88
%90 = icmp ugt i32 %32, %85
%91 = or i1 %90, %89
%92 = xor i1 %91, true
%93 = zext i1 %92 to i32
%94 = add nsw i32 %84, %93
%95 = add nuw nsw i32 %85, 1
%96 = icmp eq i32 %95, %7
br i1 %96, label %97, label %83
97: ; preds = %83, %77
%98 = phi i32 [ %79, %77 ], [ %94, %83 ]
%99 = add nuw nsw i32 %32, 1
%100 = icmp eq i32 %99, %7
br i1 %100, label %101, label %30
101: ; preds = %97
%102 = icmp slt i32 %98, 3
br i1 %102, label %103, label %123
103: ; preds = %101, %120
%104 = phi i32 [ %121, %120 ], [ 0, %101 ]
br label %105
105: ; preds = %103, %117
%106 = phi i32 [ 0, %103 ], [ %118, %117 ]
%107 = icmp ule i32 %104, %106
%108 = add nuw nsw i32 %106, %104
%109 = icmp eq i32 %108, %26
%110 = select i1 %107, i1 %109, i1 false
br i1 %110, label %111, label %117
111: ; preds = %105
%112 = icmp eq i32 %104, %106
br i1 %112, label %113, label %115
113: ; preds = %111
%114 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([26 x i8], [26 x i8]* @.str.4, i64 0, i64 0), i32 %104, i32 %104)
br label %117
115: ; preds = %111
%116 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str.5, i64 0, i64 0), i32 %104, i32 %106)
br label %117
117: ; preds = %105, %115, %113
%118 = add nuw nsw i32 %106, 1
%119 = icmp eq i32 %118, %7
br i1 %119, label %120, label %105
120: ; preds = %117
%121 = add nuw nsw i32 %104, 1
%122 = icmp eq i32 %121, %7
br i1 %122, label %153, label %103
123: ; preds = %101, %143
%124 = phi i32 [ %140, %143 ], [ 0, %101 ]
%125 = phi i32 [ %144, %143 ], [ 0, %101 ]
br label %126
126: ; preds = %123, %139
%127 = phi i32 [ %124, %123 ], [ %140, %139 ]
%128 = phi i32 [ 0, %123 ], [ %141, %139 ]
%129 = icmp eq i32 %128, %125
%130 = add nuw nsw i32 %128, %125
%131 = icmp ne i32 %130, %26
%132 = select i1 %129, i1 true, i1 %131
%133 = icmp ugt i32 %125, %128
%134 = or i1 %133, %132
br i1 %134, label %139, label %135
135: ; preds = %126
%136 = icmp eq i32 %127, 0
%137 = select i1 %136, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.6, i64 0, i64 0), i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.7, i64 0, i64 0)
%138 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) %137, i32 %125, i32 %128)
br label %139
139: ; preds = %135, %126
%140 = phi i32 [ %127, %126 ], [ 1, %135 ]
%141 = add nuw nsw i32 %128, 1
%142 = icmp eq i32 %141, %7
br i1 %142, label %143, label %126
143: ; preds = %139
%144 = add nuw nsw i32 %125, 1
%145 = icmp eq i32 %144, %7
br i1 %145, label %146, label %123
146: ; preds = %143
%147 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.8, i64 0, i64 0))
%148 = and i32 %26, 1
%149 = icmp eq i32 %148, 0
br i1 %149, label %150, label %153
150: ; preds = %146
%151 = lshr i32 %26, 1
%152 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @.str.9, i64 0, i64 0), i32 %151, i32 %151)
br label %153
153: ; preds = %120, %146, %150
%154 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([28 x i8], [28 x i8]* @.str.10, i64 0, i64 0), i32 %26)
%155 = add nuw nsw i32 %26, 1
%156 = icmp eq i32 %155, %12
br i1 %156, label %157, label %25
157: ; preds = %153, %5
%158 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([28 x i8], [28 x i8]* @.str.11, i64 0, i64 0), i32 %15)
%159 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([209 x i8], [209 x i8]* @.str.12, i64 0, i64 0), i32 %14, i32 %14, i32 %14, i32 %14)
%160 = add nuw nsw i32 %7, 1
%161 = add nuw nsw i32 %6, 2
%162 = icmp eq i32 %160, 17
br i1 %162, label %163, label %5
163: ; preds = %157
%164 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @str.15, i64 0, i64 0))
ret i32 0
}