double leibniz_pi(int iterations) {
  int counter = 1, denominator = 1;
  double piFourths = 0.0;
  while (counter <= iterations) {
    if (counter % 2 > 0 && denominator > 0) {
      piFourths += 1.0 / denominator;
    } else if (denominator > 0) {
      piFourths -= 1.0 / denominator;
    }
    counter++;
    denominator += 2;
  }
  return piFourths * 4;
}


x86 assembly (clang, -O0):
<leibniz_pi>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movl   $0x1,-0x8(%rbp)
movl   $0x1,-0xc(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x4(%rbp),%eax
jg     11ac <leibniz_pi+0xac>
mov    -0x8(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jle    1167 <leibniz_pi+0x67>
cmpl   $0x0,-0xc(%rbp)
jle    1167 <leibniz_pi+0x67>
cvtsi2sdl -0xc(%rbp),%xmm1
movsd  0xeb4(%rip),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    1195 <leibniz_pi+0x95>
cmpl   $0x0,-0xc(%rbp)
jle    1190 <leibniz_pi+0x90>
cvtsi2sdl -0xc(%rbp),%xmm0
movsd  0xe8a(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  -0x18(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
jmp    1195 <leibniz_pi+0x95>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
mov    -0xc(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0xc(%rbp)
jmp    111d <leibniz_pi+0x1d>
movsd  0xe4c(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<leibniz_pi>:
test   %edi,%edi
jle    112d <leibniz_pi+0x2d>
cmp    $0x1,%edi
jne    1131 <leibniz_pi+0x31>
mov    $0x1,%eax
movsd  0xeea(%rip),%xmm1
xorpd  %xmm0,%xmm0
test   $0x1,%dil
jne    11ae <leibniz_pi+0xae>
mulsd  0xee4(%rip),%xmm0
ret
xorps  %xmm0,%xmm0
ret
mov    %edi,%ecx
and    $0xfffffffe,%ecx
movsd  0xec2(%rip),%xmm1
xorpd  %xmm0,%xmm0
mov    $0x1,%eax
movsd  0xeb9(%rip),%xmm2
movsd  0xeb9(%rip),%xmm3
movapd %xmm1,%xmm4
mov    $0x1,%edx
movapd %xmm1,%xmm5
divsd  %xmm4,%xmm5
lea    0x2(%rdx),%esi
xorps  %xmm6,%xmm6
cvtsi2sd %esi,%xmm6
addsd  %xmm0,%xmm5
movapd %xmm2,%xmm0
divsd  %xmm6,%xmm0
addsd  %xmm5,%xmm0
addsd  %xmm3,%xmm4
add    $0x4,%edx
mov    %eax,%esi
add    $0xfffffffe,%eax
add    %ecx,%esi
add    $0xfffffffe,%esi
cmp    $0x1,%esi
jne    1160 <leibniz_pi+0x60>
neg    %eax
and    $0x1,%eax
xorps  %xmm1,%xmm1
cvtsi2sd %edx,%xmm1
test   $0x1,%dil
je     1124 <leibniz_pi+0x24>
movsd  0xe4a(%rip),%xmm2
divsd  %xmm1,%xmm2
test   %eax,%eax
jne    11c6 <leibniz_pi+0xc6>
xorpd  0xe5a(%rip),%xmm2
addsd  %xmm2,%xmm0
mulsd  0xe3e(%rip),%xmm0
ret

LLVM IR (-O0):
define double @leibniz_pi(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca double
store i32 %0, i32* %2
store i32 1, i32* %3
store i32 1, i32* %4
store double 0.000000e+00, double* %5
br label %6
6: ; preds = %33, %1
%7 = load i32, i32* %3
%8 = load i32, i32* %2
%9 = icmp sle i32 %7, %8
br i1 %9, label %10, label %38
10: ; preds = %6
%11 = load i32, i32* %3
%12 = srem i32 %11, 2
%13 = icmp sgt i32 %12, 0
br i1 %13, label %14, label %23
14: ; preds = %10
%15 = load i32, i32* %4
%16 = icmp sgt i32 %15, 0
br i1 %16, label %17, label %23
17: ; preds = %14
%18 = load i32, i32* %4
%19 = sitofp i32 %18 to double
%20 = fdiv double 1.000000e+00, %19
%21 = load double, double* %5
%22 = fadd double %21, %20
store double %22, double* %5
br label %33
23: ; preds = %14, %10
%24 = load i32, i32* %4
%25 = icmp sgt i32 %24, 0
br i1 %25, label %26, label %32
26: ; preds = %23
%27 = load i32, i32* %4
%28 = sitofp i32 %27 to double
%29 = fdiv double 1.000000e+00, %28
%30 = load double, double* %5
%31 = fsub double %30, %29
store double %31, double* %5
br label %32
32: ; preds = %26, %23
br label %33
33: ; preds = %32, %17
%34 = load i32, i32* %3
%35 = add nsw i32 %34, 1
store i32 %35, i32* %3
%36 = load i32, i32* %4
%37 = add nsw i32 %36, 2
store i32 %37, i32* %4
br label %6
38: ; preds = %6
%39 = load double, double* %5
%40 = fmul double %39, 4.000000e+00
ret double %40
}

LLVM IR (-O2):
define double @leibniz_pi(i32 %0) {
%2 = icmp slt i32 %0, 1
br i1 %2, label %42, label %3
3: ; preds = %1
%4 = and i32 %0, 1
%5 = icmp eq i32 %0, 1
br i1 %5, label %27, label %6
6: ; preds = %3
%7 = and i32 %0, -2
br label %8
8: ; preds = %8, %6
%9 = phi double [ 0.000000e+00, %6 ], [ %19, %8 ]
%10 = phi i32 [ 1, %6 ], [ %21, %8 ]
%11 = phi i32 [ 1, %6 ], [ %20, %8 ]
%12 = phi i32 [ 0, %6 ], [ %22, %8 ]
%13 = sitofp i32 %10 to double
%14 = fdiv double 1.000000e+00, %13
%15 = fadd double %9, %14
%16 = add nuw nsw i32 %10, 2
%17 = sitofp i32 %16 to double
%18 = fdiv double -1.000000e+00, %17
%19 = fadd double %15, %18
%20 = add nuw i32 %11, 2
%21 = add nuw nsw i32 %10, 4
%22 = add i32 %12, 2
%23 = icmp eq i32 %22, %7
br i1 %23, label %24, label %8
24: ; preds = %8
%25 = and i32 %11, 1
%26 = sitofp i32 %21 to double
br label %27
27: ; preds = %24, %3
%28 = phi double [ undef, %3 ], [ %19, %24 ]
%29 = phi double [ 0.000000e+00, %3 ], [ %19, %24 ]
%30 = phi double [ 1.000000e+00, %3 ], [ %26, %24 ]
%31 = phi i32 [ 1, %3 ], [ %25, %24 ]
%32 = icmp eq i32 %4, 0
br i1 %32, label %39, label %33
33: ; preds = %27
%34 = icmp eq i32 %31, 0
%35 = fdiv double 1.000000e+00, %30
%36 = fneg double %35
%37 = select i1 %34, double %36, double %35
%38 = fadd double %29, %37
br label %39
39: ; preds = %27, %33
%40 = phi double [ %28, %27 ], [ %38, %33 ]
%41 = fmul double %40, 4.000000e+00
br label %42
42: ; preds = %39, %1
%43 = phi double [ 0.000000e+00, %1 ], [ %41, %39 ]
ret double %43
}