double pi(double n) {
  double pi = 0;
  double num = 4;
  double den = 1;
  int plus = 1;
  while (den < n) {
    if (plus) {
      pi += num / den;
      plus = 0;
    } else {
      pi -= num / den;
      plus = 1;
    }
    den += 2;
  }
  return pi;
}


x86 assembly (clang, -O0):
<pi>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xeef(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xeda(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x1,-0x24(%rbp)
movsd  -0x20(%rbp),%xmm1
movsd  -0x8(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11a6 <pi+0xa6>
cmpl   $0x0,-0x24(%rbp)
je     1170 <pi+0x70>
movsd  -0x18(%rbp),%xmm0
divsd  -0x20(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
movl   $0x0,-0x24(%rbp)
jmp    118f <pi+0x8f>
movsd  -0x18(%rbp),%xmm1
divsd  -0x20(%rbp),%xmm1
movsd  -0x10(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
movl   $0x1,-0x24(%rbp)
movsd  0xe79(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1132 <pi+0x32>
movsd  -0x10(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<pi>:
xorpd  %xmm1,%xmm1
ucomisd 0xef4(%rip),%xmm0
jbe    1163 <pi+0x63>
xorpd  %xmm1,%xmm1
movsd  0xee6(%rip),%xmm2
mov    $0x1,%eax
movsd  0xee1(%rip),%xmm3
movapd 0xef1(%rip),%xmm4
movsd  0xed9(%rip),%xmm5
jmp    1151 <pi+0x51>
nopl   0x0(%rax)
addsd  %xmm6,%xmm1
xor    $0x1,%eax
addsd  %xmm5,%xmm2
ucomisd %xmm2,%xmm0
jbe    1163 <pi+0x63>
movapd %xmm3,%xmm6
divsd  %xmm2,%xmm6
test   %eax,%eax
jne    1140 <pi+0x40>
xorpd  %xmm4,%xmm6
jmp    1140 <pi+0x40>
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @pi(double %0) {
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca i32
store double %0, double* %2
store double 0.000000e+00, double* %3
store double 4.000000e+00, double* %4
store double 1.000000e+00, double* %5
store i32 1, i32* %6
br label %7
7: ; preds = %26, %1
%8 = load double, double* %5
%9 = load double, double* %2
%10 = fcmp olt double %8, %9
br i1 %10, label %11, label %29
11: ; preds = %7
%12 = load i32, i32* %6
%13 = icmp ne i32 %12, 0
br i1 %13, label %14, label %20
14: ; preds = %11
%15 = load double, double* %4
%16 = load double, double* %5
%17 = fdiv double %15, %16
%18 = load double, double* %3
%19 = fadd double %18, %17
store double %19, double* %3
store i32 0, i32* %6
br label %26
20: ; preds = %11
%21 = load double, double* %4
%22 = load double, double* %5
%23 = fdiv double %21, %22
%24 = load double, double* %3
%25 = fsub double %24, %23
store double %25, double* %3
store i32 1, i32* %6
br label %26
26: ; preds = %20, %14
%27 = load double, double* %5
%28 = fadd double %27, 2.000000e+00
store double %28, double* %5
br label %7
29: ; preds = %7
%30 = load double, double* %3
ret double %30
}

LLVM IR (-O2):
define double @pi(double %0) {
%2 = fcmp ogt double %0, 1.000000e+00
br i1 %2, label %3, label %15
3: ; preds = %1, %3
%4 = phi i32 [ %12, %3 ], [ 1, %1 ]
%5 = phi double [ %13, %3 ], [ 1.000000e+00, %1 ]
%6 = phi double [ %11, %3 ], [ 0.000000e+00, %1 ]
%7 = icmp eq i32 %4, 0
%8 = fdiv double 4.000000e+00, %5
%9 = fneg double %8
%10 = select i1 %7, double %9, double %8
%11 = fadd double %6, %10
%12 = xor i32 %4, 1
%13 = fadd double %5, 2.000000e+00
%14 = fcmp olt double %13, %0
br i1 %14, label %3, label %15
15: ; preds = %3, %1
%16 = phi double [ 0.000000e+00, %1 ], [ %11, %3 ]
ret double %16
}