#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);
void calculate_pi_2(int size) {
  printf("Calculating PI method 2 with %d digits\n", size);
  int r[size + 1];
  int i, k;
  int b, d;
  for (i = 0; i < size; i++) {
    r[i] = 2000;
  }
  for (k = size; k > 0; k -= 14) {
    d = 0;
    i = k;
    for (;;) {
      d += r[i] * 10000;
      b = 2 * i - 1;
      r[i] = d % b;
      d /= b;
      i--;
      if (i == 0)
        break;
      d *= i;
    }
  }
}


x86 assembly (clang, -O0):
<calculate_pi_2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%esi
lea    0xedb(%rip),%rdi
call   1030 <printf@plt>
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %rsp,%rcx
mov    %rcx,-0x10(%rbp)
lea    0xf(,%rax,4),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x30(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1184 <calculate_pi_2+0x74>
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movl   $0x7d0,(%rax,%rcx,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    115b <calculate_pi_2+0x4b>
mov    -0x4(%rbp),%eax
mov    %eax,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jle    121a <calculate_pi_2+0x10a>
movl   $0x0,-0x28(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   $0x2710,(%rax,%rcx,4),%eax
add    -0x28(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
shl    $0x1,%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x28(%rbp),%eax
cltd
idivl  -0x24(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%ecx
mov    -0x28(%rbp),%eax
cltd
idiv   %ecx
mov    %eax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jne    11f8 <calculate_pi_2+0xe8>
jmp    1207 <calculate_pi_2+0xf7>
mov    -0x1c(%rbp),%eax
imul   -0x28(%rbp),%eax
mov    %eax,-0x28(%rbp)
jmp    11a1 <calculate_pi_2+0x91>
jmp    120c <calculate_pi_2+0xfc>
mov    -0x20(%rbp),%eax
sub    $0xe,%eax
mov    %eax,-0x20(%rbp)
jmp    118a <calculate_pi_2+0x7a>
mov    -0x10(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calculate_pi_2>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %edi,%r14d
lea    0xeeb(%rip),%rdi
mov    %r14d,%esi
call   1030 <printf@plt>
lea    0x1(%r14),%eax
mov    %rsp,%r10
lea    0xf(,%rax,4),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r10
mov    %r10,%rsp
test   %r14d,%r14d
jle    1311 <calculate_pi_2+0x201>
mov    %r14d,%r8d
cmp    $0x8,%r14d
jae    115f <calculate_pi_2+0x4f>
xor    %eax,%eax
jmp    1260 <calculate_pi_2+0x150>
mov    %r8d,%eax
and    $0xfffffff8,%eax
lea    -0x8(%rax),%rsi
mov    %rsi,%rdx
shr    $0x3,%rdx
add    $0x1,%rdx
mov    %edx,%ecx
and    $0x7,%ecx
cmp    $0x38,%rsi
jae    1186 <calculate_pi_2+0x76>
xor    %esi,%esi
jmp    1225 <calculate_pi_2+0x115>
and    $0xfffffffffffffff8,%rdx
xor    %esi,%esi
movaps 0xe6d(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movaps %xmm0,(%r10,%rsi,4)
movaps %xmm0,0x10(%r10,%rsi,4)
movaps %xmm0,0x20(%r10,%rsi,4)
movaps %xmm0,0x30(%r10,%rsi,4)
movaps %xmm0,0x40(%r10,%rsi,4)
movaps %xmm0,0x50(%r10,%rsi,4)
movaps %xmm0,0x60(%r10,%rsi,4)
movaps %xmm0,0x70(%r10,%rsi,4)
movaps %xmm0,0x80(%r10,%rsi,4)
movaps %xmm0,0x90(%r10,%rsi,4)
movaps %xmm0,0xa0(%r10,%rsi,4)
movaps %xmm0,0xb0(%r10,%rsi,4)
movaps %xmm0,0xc0(%r10,%rsi,4)
movaps %xmm0,0xd0(%r10,%rsi,4)
movaps %xmm0,0xe0(%r10,%rsi,4)
movaps %xmm0,0xf0(%r10,%rsi,4)
add    $0x40,%rsi
add    $0xfffffffffffffff8,%rdx
jne    11a0 <calculate_pi_2+0x90>
test   %rcx,%rcx
je     1252 <calculate_pi_2+0x142>
lea    (%r10,%rsi,4),%rdx
add    $0x10,%rdx
shl    $0x5,%rcx
xor    %esi,%esi
movaps 0xdc1(%rip),%xmm0
nop
movaps %xmm0,-0x10(%rdx,%rsi,1)
movaps %xmm0,(%rdx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%rcx
jne    1240 <calculate_pi_2+0x130>
cmp    %r8,%rax
je     1271 <calculate_pi_2+0x161>
nopw   0x0(%rax,%rax,1)
movl   $0x7d0,(%r10,%rax,4)
add    $0x1,%rax
cmp    %rax,%r8
jne    1260 <calculate_pi_2+0x150>
test   %r14d,%r14d
jle    1311 <calculate_pi_2+0x201>
lea    -0x1(%r14),%r9d
lea    (%r14,%r14,1),%r15d
add    $0xfffffffe,%r15d
or     $0x1,%r15
add    %r14d,%r14d
add    $0xfffffffc,%r14d
or     $0x1,%r14
lea    (%r10,%r9,4),%r12
xor    %r11d,%r11d
nopl   0x0(%rax)
imul   $0x2710,(%r10,%r8,4),%ecx
lea    (%r8,%r8,1),%edi
add    $0xffffffff,%edi
mov    %ecx,%eax
cltd
idiv   %edi
mov    %edx,(%r10,%r8,4)
cmp    $0x1,%r8
je     1311 <calculate_pi_2+0x201>
mov    %r11,%rdi
mov    %r9d,%ebx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    (%r15,%rdi,1),%esi
mov    %ecx,%eax
cltd
idiv   %esi
imul   $0x2710,(%r12,%rdi,2),%ecx
imul   %ebx,%eax
add    %eax,%ecx
lea    (%r14,%rdi,1),%esi
mov    %ecx,%eax
cltd
idiv   %esi
mov    %edx,(%r12,%rdi,2)
add    $0xfffffffffffffffe,%rdi
add    $0xffffffff,%ebx
jne    12d0 <calculate_pi_2+0x1c0>
lea    -0xe(%r8),%rax
add    $0xfffffff2,%r9d
add    $0xffffffffffffffe4,%r11
cmp    $0xe,%r8
mov    %rax,%r8
jg     12a0 <calculate_pi_2+0x190>
lea    -0x20(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [40 x i8] c"Calculating PI method 2 with %d digits\0A\00"
define void @calculate_pi_2(i32 %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i64
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i32 %0, i32* %2
%9 = load i32, i32* %2
%10 = call i32 @printf(i8* getelementptr inbounds ([40 x i8], [40 x i8]* @.str, i64 0, i64 0), i32 %9)
%11 = load i32, i32* %2
%12 = add nsw i32 %11, 1
%13 = zext i32 %12 to i64
%14 = call i8* @llvm.stacksave()
store i8* %14, i8** %3
%15 = alloca i32, i64 %13
store i64 %13, i64* %4
store i32 0, i32* %5
br label %16
16: ; preds = %24, %1
%17 = load i32, i32* %5
%18 = load i32, i32* %2
%19 = icmp slt i32 %17, %18
br i1 %19, label %20, label %27
20: ; preds = %16
%21 = load i32, i32* %5
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds i32, i32* %15, i64 %22
store i32 2000, i32* %23
br label %24
24: ; preds = %20
%25 = load i32, i32* %5
%26 = add nsw i32 %25, 1
store i32 %26, i32* %5
br label %16
27: ; preds = %16
%28 = load i32, i32* %2
store i32 %28, i32* %6
br label %29
29: ; preds = %64, %27
%30 = load i32, i32* %6
%31 = icmp sgt i32 %30, 0
br i1 %31, label %32, label %67
32: ; preds = %29
store i32 0, i32* %8
%33 = load i32, i32* %6
store i32 %33, i32* %5
br label %34
34: ; preds = %59, %32
%35 = load i32, i32* %5
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i32, i32* %15, i64 %36
%38 = load i32, i32* %37
%39 = mul nsw i32 %38, 10000
%40 = load i32, i32* %8
%41 = add nsw i32 %40, %39
store i32 %41, i32* %8
%42 = load i32, i32* %5
%43 = mul nsw i32 2, %42
%44 = sub nsw i32 %43, 1
store i32 %44, i32* %7
%45 = load i32, i32* %8
%46 = load i32, i32* %7
%47 = srem i32 %45, %46
%48 = load i32, i32* %5
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds i32, i32* %15, i64 %49
store i32 %47, i32* %50
%51 = load i32, i32* %7
%52 = load i32, i32* %8
%53 = sdiv i32 %52, %51
store i32 %53, i32* %8
%54 = load i32, i32* %5
%55 = add nsw i32 %54, -1
store i32 %55, i32* %5
%56 = load i32, i32* %5
%57 = icmp eq i32 %56, 0
br i1 %57, label %58, label %59
58: ; preds = %34
br label %63
59: ; preds = %34
%60 = load i32, i32* %5
%61 = load i32, i32* %8
%62 = mul nsw i32 %61, %60
store i32 %62, i32* %8
br label %34
63: ; preds = %58
br label %64
64: ; preds = %63
%65 = load i32, i32* %6
%66 = sub nsw i32 %65, 14
store i32 %66, i32* %6
br label %29
67: ; preds = %29
%68 = load i8*, i8** %3
ret void
}

LLVM IR (-O2):
@.str = [40 x i8] c"Calculating PI method 2 with %d digits\0A\00"
define void @calculate_pi_2(i32 %0) {
%2 = tail call i32 @printf(i8* getelementptr inbounds ([40 x i8], [40 x i8]* @.str, i64 0, i64 0), i32 %0)
%3 = add nsw i32 %0, 1
%4 = zext i32 %3 to i64
%5 = alloca i32, i64 %4
%6 = icmp sgt i32 %0, 0
br i1 %6, label %7, label %123
7: ; preds = %1
%8 = zext i32 %0 to i64
%9 = icmp ult i32 %0, 8
br i1 %9, label %79, label %10
10: ; preds = %7
%11 = and i64 %8, 4294967288
%12 = add nsw i64 %11, -8
%13 = lshr exact i64 %12, 3
%14 = add nuw nsw i64 %13, 1
%15 = and i64 %14, 7
%16 = icmp ult i64 %12, 56
br i1 %16, label %64, label %17
17: ; preds = %10
%18 = and i64 %14, 4611686018427387896
br label %19
19: ; preds = %19, %17
%20 = phi i64 [ 0, %17 ], [ %61, %19 ]
%21 = phi i64 [ 0, %17 ], [ %62, %19 ]
%22 = getelementptr inbounds i32, i32* %5, i64 %20
%23 = bitcast i32* %22 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %23
%24 = getelementptr inbounds i32, i32* %22, i64 4
%25 = bitcast i32* %24 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %25
%26 = or i64 %20, 8
%27 = getelementptr inbounds i32, i32* %5, i64 %26
%28 = bitcast i32* %27 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %28
%29 = getelementptr inbounds i32, i32* %27, i64 4
%30 = bitcast i32* %29 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %30
%31 = or i64 %20, 16
%32 = getelementptr inbounds i32, i32* %5, i64 %31
%33 = bitcast i32* %32 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %33
%34 = getelementptr inbounds i32, i32* %32, i64 4
%35 = bitcast i32* %34 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %35
%36 = or i64 %20, 24
%37 = getelementptr inbounds i32, i32* %5, i64 %36
%38 = bitcast i32* %37 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %38
%39 = getelementptr inbounds i32, i32* %37, i64 4
%40 = bitcast i32* %39 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %40
%41 = or i64 %20, 32
%42 = getelementptr inbounds i32, i32* %5, i64 %41
%43 = bitcast i32* %42 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %43
%44 = getelementptr inbounds i32, i32* %42, i64 4
%45 = bitcast i32* %44 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %45
%46 = or i64 %20, 40
%47 = getelementptr inbounds i32, i32* %5, i64 %46
%48 = bitcast i32* %47 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %48
%49 = getelementptr inbounds i32, i32* %47, i64 4
%50 = bitcast i32* %49 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %50
%51 = or i64 %20, 48
%52 = getelementptr inbounds i32, i32* %5, i64 %51
%53 = bitcast i32* %52 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %53
%54 = getelementptr inbounds i32, i32* %52, i64 4
%55 = bitcast i32* %54 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %55
%56 = or i64 %20, 56
%57 = getelementptr inbounds i32, i32* %5, i64 %56
%58 = bitcast i32* %57 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %58
%59 = getelementptr inbounds i32, i32* %57, i64 4
%60 = bitcast i32* %59 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %60
%61 = add nuw i64 %20, 64
%62 = add nuw i64 %21, 8
%63 = icmp eq i64 %62, %18
br i1 %63, label %64, label %19
64: ; preds = %19, %10
%65 = phi i64 [ 0, %10 ], [ %61, %19 ]
%66 = icmp eq i64 %15, 0
br i1 %66, label %77, label %67
67: ; preds = %64, %67
%68 = phi i64 [ %74, %67 ], [ %65, %64 ]
%69 = phi i64 [ %75, %67 ], [ 0, %64 ]
%70 = getelementptr inbounds i32, i32* %5, i64 %68
%71 = bitcast i32* %70 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %71
%72 = getelementptr inbounds i32, i32* %70, i64 4
%73 = bitcast i32* %72 to <4 x i32>*
store <4 x i32> <i32 2000, i32 2000, i32 2000, i32 2000>, <4 x i32>* %73
%74 = add nuw i64 %68, 8
%75 = add i64 %69, 1
%76 = icmp eq i64 %75, %15
br i1 %76, label %77, label %67
77: ; preds = %67, %64
%78 = icmp eq i64 %11, %8
br i1 %78, label %81, label %79
79: ; preds = %7, %77
%80 = phi i64 [ 0, %7 ], [ %11, %77 ]
br label %86
81: ; preds = %86, %77
br i1 %6, label %82, label %123
82: ; preds = %81
%83 = add nsw i32 %0, -1
%84 = zext i32 %83 to i64
%85 = zext i32 %0 to i64
br label %91
86: ; preds = %79, %86
%87 = phi i64 [ %89, %86 ], [ %80, %79 ]
%88 = getelementptr inbounds i32, i32* %5, i64 %87
store i32 2000, i32* %88
%89 = add nuw nsw i64 %87, 1
%90 = icmp eq i64 %89, %8
br i1 %90, label %81, label %86
91: ; preds = %82, %119
%92 = phi i64 [ %85, %82 ], [ %120, %119 ]
%93 = phi i64 [ %84, %82 ], [ %122, %119 ]
%94 = trunc i64 %92 to i32
%95 = getelementptr inbounds i32, i32* %5, i64 %92
%96 = load i32, i32* %95
%97 = mul nsw i32 %96, 10000
%98 = shl nsw i32 %94, 1
%99 = add nsw i32 %98, -1
%100 = srem i32 %97, %99
store i32 %100, i32* %95
%101 = icmp eq i64 %92, 1
br i1 %101, label %123, label %102
102: ; preds = %91, %102
%103 = phi i64 [ %116, %102 ], [ %93, %91 ]
%104 = phi i32 [ %114, %102 ], [ %99, %91 ]
%105 = phi i32 [ %112, %102 ], [ %97, %91 ]
%106 = trunc i64 %103 to i32
%107 = sdiv i32 %105, %104
%108 = mul nsw i32 %107, %106
%109 = getelementptr inbounds i32, i32* %5, i64 %103
%110 = load i32, i32* %109
%111 = mul nsw i32 %110, 10000
%112 = add nsw i32 %111, %108
%113 = shl nsw i32 %106, 1
%114 = add nsw i32 %113, -1
%115 = srem i32 %112, %114
store i32 %115, i32* %109
%116 = add nsw i64 %103, -1
%117 = trunc i64 %116 to i32
%118 = icmp eq i32 %117, 0
br i1 %118, label %119, label %102
119: ; preds = %102
%120 = add nsw i64 %92, -14
%121 = icmp sgt i64 %92, 14
%122 = add nsw i64 %93, -14
br i1 %121, label %91, label %123
123: ; preds = %91, %119, %1, %81
ret void
}