int fast_expansion_sum(int elen, double *e, int flen, double *f, double *h) {
  double Q;
  double Qnew;
  double bvirt;
  double avirt, bround, around;
  int eindex, findex, hindex;
  eindex = findex = 0;
  if (((f[findex]) > (e[eindex])) == ((f[findex]) > -(e[eindex]))) {
    Q = (e[eindex]);
    ++eindex;
  } else {
    Q = (f[findex]);
    ++findex;
  }
  hindex = 0;
  if ((eindex < elen) && (findex < flen)) {
    if (((f[findex]) > (e[eindex])) == ((f[findex]) > -(e[eindex]))) {
      Qnew = (double)((e[eindex]) + Q);
      bvirt = Qnew - (e[eindex]);
      h[0] = Q - bvirt;
      ++eindex;
    } else {
      Qnew = (double)((f[findex]) + Q);
      bvirt = Qnew - (f[findex]);
      h[0] = Q - bvirt;
      ++findex;
    }
    Q = Qnew;
    hindex = 1;
    while ((eindex < elen) && (findex < flen)) {
      if (((f[findex]) > (e[eindex])) == ((f[findex]) > -(e[eindex]))) {
        Qnew = (double)(Q + (e[eindex]));
        bvirt = (double)(Qnew - Q);
        avirt = Qnew - bvirt;
        bround = (e[eindex]) - bvirt;
        around = Q - avirt;
        h[hindex] = around + bround;
        ++eindex;
      } else {
        Qnew = (double)(Q + (f[findex]));
        bvirt = (double)(Qnew - Q);
        avirt = Qnew - bvirt;
        bround = (f[findex]) - bvirt;
        around = Q - avirt;
        h[hindex] = around + bround;
        ++findex;
      }
      Q = Qnew;
      hindex++;
    }
  }
  while (eindex < elen) {
    Qnew = (double)(Q + (e[eindex]));
    bvirt = (double)(Qnew - Q);
    avirt = Qnew - bvirt;
    bround = (e[eindex]) - bvirt;
    around = Q - avirt;
    h[hindex] = around + bround;
    ++eindex;
    Q = Qnew;
    hindex++;
  }
  while (findex < flen) {
    Qnew = (double)(Q + (f[findex]));
    bvirt = (double)(Qnew - Q);
    avirt = Qnew - bvirt;
    bround = (f[findex]) - bvirt;
    around = Q - avirt;
    h[hindex] = around + bround;
    ++findex;
    Q = Qnew;
    hindex++;
  }
  h[hindex] = Q;
  return hindex + 1;
}


x86 assembly (clang, -O0):
<fast_expansion_sum>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
movl   $0x0,-0x60(%rbp)
movl   $0x0,-0x5c(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    -0x20(%rbp),%rcx
movslq -0x60(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x10(%rbp),%rcx
movslq -0x5c(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm1
movq   %xmm1,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm1
ucomisd %xmm1,%xmm0
seta   %cl
and    $0x1,%cl
movzbl %cl,%ecx
cmp    %ecx,%eax
jne    11ac <fast_expansion_sum+0xac>
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    11c7 <fast_expansion_sum+0xc7>
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x60(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x60(%rbp)
movl   $0x0,-0x64(%rbp)
mov    -0x5c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    14a3 <fast_expansion_sum+0x3a3>
mov    -0x60(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    14a3 <fast_expansion_sum+0x3a3>
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    -0x20(%rbp),%rcx
movslq -0x60(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x10(%rbp),%rcx
movslq -0x5c(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm1
movq   %xmm1,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm1
ucomisd %xmm1,%xmm0
seta   %cl
and    $0x1,%cl
movzbl %cl,%ecx
cmp    %ecx,%eax
jne    129c <fast_expansion_sum+0x19c>
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    12e5 <fast_expansion_sum+0x1e5>
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x60(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x60(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movl   $0x1,-0x64(%rbp)
mov    -0x5c(%rbp),%ecx
xor    %eax,%eax
cmp    -0x4(%rbp),%ecx
mov    %al,-0x65(%rbp)
jge    1313 <fast_expansion_sum+0x213>
mov    -0x60(%rbp),%eax
cmp    -0x14(%rbp),%eax
setl   %al
mov    %al,-0x65(%rbp)
mov    -0x65(%rbp),%al
test   $0x1,%al
jne    1323 <fast_expansion_sum+0x223>
jmp    149e <fast_expansion_sum+0x39e>
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
ucomisd (%rax,%rcx,8),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
mov    -0x20(%rbp),%rcx
movslq -0x60(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x10(%rbp),%rcx
movslq -0x5c(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm1
movq   %xmm1,%rcx
movabs $0x8000000000000000,%rdx
xor    %rdx,%rcx
movq   %rcx,%xmm1
ucomisd %xmm1,%xmm0
seta   %cl
and    $0x1,%cl
movzbl %cl,%ecx
cmp    %ecx,%eax
jne    140b <fast_expansion_sum+0x30b>
movsd  -0x30(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    1486 <fast_expansion_sum+0x386>
movsd  -0x30(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x60(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x60(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    12f6 <fast_expansion_sum+0x1f6>
jmp    14a3 <fast_expansion_sum+0x3a3>
jmp    14a8 <fast_expansion_sum+0x3a8>
mov    -0x5c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1547 <fast_expansion_sum+0x447>
movsd  -0x30(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    14a8 <fast_expansion_sum+0x3a8>
jmp    154c <fast_expansion_sum+0x44c>
mov    -0x60(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    15eb <fast_expansion_sum+0x4eb>
movsd  -0x30(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x60(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x60(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x60(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    154c <fast_expansion_sum+0x44c>
movsd  -0x30(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<fast_expansion_sum>:
push   %r14
push   %rbx
movsd  (%rcx),%xmm1
movsd  (%rsi),%xmm0
ucomisd %xmm0,%xmm1
setbe  %bl
movapd 0xee6(%rip),%xmm2
xorpd  %xmm0,%xmm2
ucomisd %xmm2,%xmm1
seta   %al
xor    %bl,%al
jne    112d <fast_expansion_sum+0x2d>
movapd %xmm1,%xmm0
movzbl %al,%r10d
mov    %r10d,%eax
xor    $0x1,%al
movzbl %al,%r9d
xor    %eax,%eax
cmp    %edi,%r10d
jge    1298 <fast_expansion_sum+0x198>
cmp    %edx,%r9d
jge    1298 <fast_expansion_sum+0x198>
mov    %r9d,%eax
movsd  (%rcx,%rax,8),%xmm1
mov    %r10d,%eax
movsd  (%rsi,%rax,8),%xmm2
ucomisd %xmm2,%xmm1
setbe  %al
movapd 0xe93(%rip),%xmm3
xorpd  %xmm2,%xmm3
ucomisd %xmm3,%xmm1
seta   %bl
cmp    %bl,%al
je     119f <fast_expansion_sum+0x9f>
movapd %xmm0,%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,%xmm3
subsd  %xmm2,%xmm3
subsd  %xmm3,%xmm0
movsd  %xmm0,(%r8)
add    $0x1,%r10d
movapd %xmm1,%xmm0
jmp    11c5 <fast_expansion_sum+0xc5>
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movapd %xmm2,%xmm3
subsd  %xmm1,%xmm3
subsd  %xmm3,%xmm0
movsd  %xmm0,(%r8)
mov    $0x2,%r9d
sub    %r10d,%r9d
movapd %xmm2,%xmm0
mov    $0x1,%eax
cmp    %edi,%r10d
jge    1298 <fast_expansion_sum+0x198>
cmp    %edx,%r9d
jge    1298 <fast_expansion_sum+0x198>
mov    $0x1,%eax
movapd 0xe17(%rip),%xmm1
nopl   0x0(%rax)
movslq %r9d,%rbx
movsd  (%rcx,%rbx,8),%xmm2
movslq %r10d,%rbx
movsd  (%rsi,%rbx,8),%xmm3
ucomisd %xmm3,%xmm2
setbe  %r11b
movapd %xmm3,%xmm4
xorpd  %xmm1,%xmm4
ucomisd %xmm4,%xmm2
seta   %bl
cmp    %bl,%r11b
je     1250 <fast_expansion_sum+0x150>
movapd %xmm0,%xmm4
addsd  %xmm3,%xmm4
movapd %xmm4,%xmm2
subsd  %xmm0,%xmm2
movapd %xmm4,%xmm5
subsd  %xmm2,%xmm5
subsd  %xmm2,%xmm3
subsd  %xmm5,%xmm0
addsd  %xmm3,%xmm0
add    $0x1,%r10d
movapd %xmm0,%xmm2
movapd %xmm4,%xmm0
jmp    1280 <fast_expansion_sum+0x180>
xchg   %ax,%ax
movapd %xmm0,%xmm3
addsd  %xmm2,%xmm3
movapd %xmm3,%xmm4
subsd  %xmm0,%xmm4
movapd %xmm3,%xmm5
subsd  %xmm4,%xmm5
subsd  %xmm4,%xmm2
subsd  %xmm5,%xmm0
addsd  %xmm2,%xmm0
add    $0x1,%r9d
movapd %xmm0,%xmm2
movapd %xmm3,%xmm0
movsd  %xmm2,(%r8,%rax,8)
add    $0x1,%rax
cmp    %edi,%r10d
jge    1298 <fast_expansion_sum+0x198>
cmp    %edx,%r9d
jl     11f0 <fast_expansion_sum+0xf0>
cmp    %edi,%r10d
jge    138a <fast_expansion_sum+0x28a>
mov    %eax,%eax
movslq %r10d,%r14
movslq %edi,%r11
sub    %r10d,%edi
mov    %r14,%rbx
not    %rbx
test   $0x1,%dil
je     12f4 <fast_expansion_sum+0x1f4>
movsd  (%rsi,%r14,8),%xmm1
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movapd %xmm2,%xmm3
subsd  %xmm0,%xmm3
movapd %xmm2,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%r8,%rax,8)
add    $0x1,%r14
add    $0x1,%rax
movapd %xmm2,%xmm0
add    %r11,%rbx
je     138a <fast_expansion_sum+0x28a>
sub    %r14,%r11
lea    (%rsi,%r14,8),%rdi
add    $0x8,%rdi
lea    (%r8,%rax,8),%rbx
add    $0x8,%rbx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  -0x8(%rdi,%rsi,8),%xmm1
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movapd %xmm2,%xmm3
subsd  %xmm0,%xmm3
movapd %xmm2,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbx,%rsi,8)
movsd  (%rdi,%rsi,8),%xmm1
movapd %xmm2,%xmm0
addsd  %xmm1,%xmm0
movapd %xmm0,%xmm3
subsd  %xmm2,%xmm3
movapd %xmm0,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm2
addsd  %xmm1,%xmm2
movsd  %xmm2,(%rbx,%rsi,8)
add    $0x2,%rsi
cmp    %rsi,%r11
jne    1320 <fast_expansion_sum+0x220>
add    %rsi,%rax
cmp    %edx,%r9d
jge    147a <fast_expansion_sum+0x37a>
mov    %eax,%eax
movslq %r9d,%rbx
movslq %edx,%rsi
sub    %r9d,%edx
mov    %rbx,%rdi
not    %rdi
test   $0x1,%dl
je     13e4 <fast_expansion_sum+0x2e4>
movsd  (%rcx,%rbx,8),%xmm1
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movapd %xmm2,%xmm3
subsd  %xmm0,%xmm3
movapd %xmm2,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%r8,%rax,8)
add    $0x1,%rbx
add    $0x1,%rax
movapd %xmm2,%xmm0
add    %rsi,%rdi
je     147a <fast_expansion_sum+0x37a>
sub    %rbx,%rsi
lea    (%rcx,%rbx,8),%rdx
add    $0x8,%rdx
lea    (%r8,%rax,8),%rdi
add    $0x8,%rdi
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  -0x8(%rdx,%rcx,8),%xmm1
movapd %xmm0,%xmm2
addsd  %xmm1,%xmm2
movapd %xmm2,%xmm3
subsd  %xmm0,%xmm3
movapd %xmm2,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rdi,%rcx,8)
movsd  (%rdx,%rcx,8),%xmm1
movapd %xmm2,%xmm0
addsd  %xmm1,%xmm0
movapd %xmm0,%xmm3
subsd  %xmm2,%xmm3
movapd %xmm0,%xmm4
subsd  %xmm3,%xmm4
subsd  %xmm3,%xmm1
subsd  %xmm4,%xmm2
addsd  %xmm1,%xmm2
movsd  %xmm2,(%rdi,%rcx,8)
add    $0x2,%rcx
cmp    %rcx,%rsi
jne    1410 <fast_expansion_sum+0x310>
add    %rcx,%rax
mov    %eax,%ecx
movsd  %xmm0,(%r8,%rcx,8)
add    $0x1,%eax
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define i32 @fast_expansion_sum(i32 %0, double* %1, i32 %2, double* %3, double* %4) {
%6 = alloca i32
%7 = alloca double*
%8 = alloca i32
%9 = alloca double*
%10 = alloca double*
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
store i32 %0, i32* %6
store double* %1, double** %7
store i32 %2, i32* %8
store double* %3, double** %9
store double* %4, double** %10
store i32 0, i32* %18
store i32 0, i32* %17
%20 = load double*, double** %9
%21 = load i32, i32* %18
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds double, double* %20, i64 %22
%24 = load double, double* %23
%25 = load double*, double** %7
%26 = load i32, i32* %17
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds double, double* %25, i64 %27
%29 = load double, double* %28
%30 = fcmp ogt double %24, %29
%31 = zext i1 %30 to i32
%32 = load double*, double** %9
%33 = load i32, i32* %18
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds double, double* %32, i64 %34
%36 = load double, double* %35
%37 = load double*, double** %7
%38 = load i32, i32* %17
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %37, i64 %39
%41 = load double, double* %40
%42 = fneg double %41
%43 = fcmp ogt double %36, %42
%44 = zext i1 %43 to i32
%45 = icmp eq i32 %31, %44
br i1 %45, label %46, label %54
46: ; preds = %5
%47 = load double*, double** %7
%48 = load i32, i32* %17
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds double, double* %47, i64 %49
%51 = load double, double* %50
store double %51, double* %11
%52 = load i32, i32* %17
%53 = add nsw i32 %52, 1
store i32 %53, i32* %17
br label %62
54: ; preds = %5
%55 = load double*, double** %9
%56 = load i32, i32* %18
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds double, double* %55, i64 %57
%59 = load double, double* %58
store double %59, double* %11
%60 = load i32, i32* %18
%61 = add nsw i32 %60, 1
store i32 %61, i32* %18
br label %62
62: ; preds = %54, %46
store i32 0, i32* %19
%63 = load i32, i32* %17
%64 = load i32, i32* %6
%65 = icmp slt i32 %63, %64
br i1 %65, label %66, label %251
66: ; preds = %62
%67 = load i32, i32* %18
%68 = load i32, i32* %8
%69 = icmp slt i32 %67, %68
br i1 %69, label %70, label %251
70: ; preds = %66
%71 = load double*, double** %9
%72 = load i32, i32* %18
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds double, double* %71, i64 %73
%75 = load double, double* %74
%76 = load double*, double** %7
%77 = load i32, i32* %17
%78 = sext i32 %77 to i64
%79 = getelementptr inbounds double, double* %76, i64 %78
%80 = load double, double* %79
%81 = fcmp ogt double %75, %80
%82 = zext i1 %81 to i32
%83 = load double*, double** %9
%84 = load i32, i32* %18
%85 = sext i32 %84 to i64
%86 = getelementptr inbounds double, double* %83, i64 %85
%87 = load double, double* %86
%88 = load double*, double** %7
%89 = load i32, i32* %17
%90 = sext i32 %89 to i64
%91 = getelementptr inbounds double, double* %88, i64 %90
%92 = load double, double* %91
%93 = fneg double %92
%94 = fcmp ogt double %87, %93
%95 = zext i1 %94 to i32
%96 = icmp eq i32 %82, %95
br i1 %96, label %97, label %119
97: ; preds = %70
%98 = load double*, double** %7
%99 = load i32, i32* %17
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds double, double* %98, i64 %100
%102 = load double, double* %101
%103 = load double, double* %11
%104 = fadd double %102, %103
store double %104, double* %12
%105 = load double, double* %12
%106 = load double*, double** %7
%107 = load i32, i32* %17
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds double, double* %106, i64 %108
%110 = load double, double* %109
%111 = fsub double %105, %110
store double %111, double* %13
%112 = load double, double* %11
%113 = load double, double* %13
%114 = fsub double %112, %113
%115 = load double*, double** %10
%116 = getelementptr inbounds double, double* %115, i64 0
store double %114, double* %116
%117 = load i32, i32* %17
%118 = add nsw i32 %117, 1
store i32 %118, i32* %17
br label %141
119: ; preds = %70
%120 = load double*, double** %9
%121 = load i32, i32* %18
%122 = sext i32 %121 to i64
%123 = getelementptr inbounds double, double* %120, i64 %122
%124 = load double, double* %123
%125 = load double, double* %11
%126 = fadd double %124, %125
store double %126, double* %12
%127 = load double, double* %12
%128 = load double*, double** %9
%129 = load i32, i32* %18
%130 = sext i32 %129 to i64
%131 = getelementptr inbounds double, double* %128, i64 %130
%132 = load double, double* %131
%133 = fsub double %127, %132
store double %133, double* %13
%134 = load double, double* %11
%135 = load double, double* %13
%136 = fsub double %134, %135
%137 = load double*, double** %10
%138 = getelementptr inbounds double, double* %137, i64 0
store double %136, double* %138
%139 = load i32, i32* %18
%140 = add nsw i32 %139, 1
store i32 %140, i32* %18
br label %141
141: ; preds = %119, %97
%142 = load double, double* %12
store double %142, double* %11
store i32 1, i32* %19
br label %143
143: ; preds = %246, %141
%144 = load i32, i32* %17
%145 = load i32, i32* %6
%146 = icmp slt i32 %144, %145
br i1 %146, label %147, label %151
147: ; preds = %143
%148 = load i32, i32* %18
%149 = load i32, i32* %8
%150 = icmp slt i32 %148, %149
br label %151
151: ; preds = %147, %143
%152 = phi i1 [ false, %143 ], [ %150, %147 ]
br i1 %152, label %153, label %250
153: ; preds = %151
%154 = load double*, double** %9
%155 = load i32, i32* %18
%156 = sext i32 %155 to i64
%157 = getelementptr inbounds double, double* %154, i64 %156
%158 = load double, double* %157
%159 = load double*, double** %7
%160 = load i32, i32* %17
%161 = sext i32 %160 to i64
%162 = getelementptr inbounds double, double* %159, i64 %161
%163 = load double, double* %162
%164 = fcmp ogt double %158, %163
%165 = zext i1 %164 to i32
%166 = load double*, double** %9
%167 = load i32, i32* %18
%168 = sext i32 %167 to i64
%169 = getelementptr inbounds double, double* %166, i64 %168
%170 = load double, double* %169
%171 = load double*, double** %7
%172 = load i32, i32* %17
%173 = sext i32 %172 to i64
%174 = getelementptr inbounds double, double* %171, i64 %173
%175 = load double, double* %174
%176 = fneg double %175
%177 = fcmp ogt double %170, %176
%178 = zext i1 %177 to i32
%179 = icmp eq i32 %165, %178
br i1 %179, label %180, label %213
180: ; preds = %153
%181 = load double, double* %11
%182 = load double*, double** %7
%183 = load i32, i32* %17
%184 = sext i32 %183 to i64
%185 = getelementptr inbounds double, double* %182, i64 %184
%186 = load double, double* %185
%187 = fadd double %181, %186
store double %187, double* %12
%188 = load double, double* %12
%189 = load double, double* %11
%190 = fsub double %188, %189
store double %190, double* %13
%191 = load double, double* %12
%192 = load double, double* %13
%193 = fsub double %191, %192
store double %193, double* %14
%194 = load double*, double** %7
%195 = load i32, i32* %17
%196 = sext i32 %195 to i64
%197 = getelementptr inbounds double, double* %194, i64 %196
%198 = load double, double* %197
%199 = load double, double* %13
%200 = fsub double %198, %199
store double %200, double* %15
%201 = load double, double* %11
%202 = load double, double* %14
%203 = fsub double %201, %202
store double %203, double* %16
%204 = load double, double* %16
%205 = load double, double* %15
%206 = fadd double %204, %205
%207 = load double*, double** %10
%208 = load i32, i32* %19
%209 = sext i32 %208 to i64
%210 = getelementptr inbounds double, double* %207, i64 %209
store double %206, double* %210
%211 = load i32, i32* %17
%212 = add nsw i32 %211, 1
store i32 %212, i32* %17
br label %246
213: ; preds = %153
%214 = load double, double* %11
%215 = load double*, double** %9
%216 = load i32, i32* %18
%217 = sext i32 %216 to i64
%218 = getelementptr inbounds double, double* %215, i64 %217
%219 = load double, double* %218
%220 = fadd double %214, %219
store double %220, double* %12
%221 = load double, double* %12
%222 = load double, double* %11
%223 = fsub double %221, %222
store double %223, double* %13
%224 = load double, double* %12
%225 = load double, double* %13
%226 = fsub double %224, %225
store double %226, double* %14
%227 = load double*, double** %9
%228 = load i32, i32* %18
%229 = sext i32 %228 to i64
%230 = getelementptr inbounds double, double* %227, i64 %229
%231 = load double, double* %230
%232 = load double, double* %13
%233 = fsub double %231, %232
store double %233, double* %15
%234 = load double, double* %11
%235 = load double, double* %14
%236 = fsub double %234, %235
store double %236, double* %16
%237 = load double, double* %16
%238 = load double, double* %15
%239 = fadd double %237, %238
%240 = load double*, double** %10
%241 = load i32, i32* %19
%242 = sext i32 %241 to i64
%243 = getelementptr inbounds double, double* %240, i64 %242
store double %239, double* %243
%244 = load i32, i32* %18
%245 = add nsw i32 %244, 1
store i32 %245, i32* %18
br label %246
246: ; preds = %213, %180
%247 = load double, double* %12
store double %247, double* %11
%248 = load i32, i32* %19
%249 = add nsw i32 %248, 1
store i32 %249, i32* %19
br label %143
250: ; preds = %151
br label %251
251: ; preds = %250, %66, %62
br label %252
252: ; preds = %256, %251
%253 = load i32, i32* %17
%254 = load i32, i32* %6
%255 = icmp slt i32 %253, %254
br i1 %255, label %256, label %292
256: ; preds = %252
%257 = load double, double* %11
%258 = load double*, double** %7
%259 = load i32, i32* %17
%260 = sext i32 %259 to i64
%261 = getelementptr inbounds double, double* %258, i64 %260
%262 = load double, double* %261
%263 = fadd double %257, %262
store double %263, double* %12
%264 = load double, double* %12
%265 = load double, double* %11
%266 = fsub double %264, %265
store double %266, double* %13
%267 = load double, double* %12
%268 = load double, double* %13
%269 = fsub double %267, %268
store double %269, double* %14
%270 = load double*, double** %7
%271 = load i32, i32* %17
%272 = sext i32 %271 to i64
%273 = getelementptr inbounds double, double* %270, i64 %272
%274 = load double, double* %273
%275 = load double, double* %13
%276 = fsub double %274, %275
store double %276, double* %15
%277 = load double, double* %11
%278 = load double, double* %14
%279 = fsub double %277, %278
store double %279, double* %16
%280 = load double, double* %16
%281 = load double, double* %15
%282 = fadd double %280, %281
%283 = load double*, double** %10
%284 = load i32, i32* %19
%285 = sext i32 %284 to i64
%286 = getelementptr inbounds double, double* %283, i64 %285
store double %282, double* %286
%287 = load i32, i32* %17
%288 = add nsw i32 %287, 1
store i32 %288, i32* %17
%289 = load double, double* %12
store double %289, double* %11
%290 = load i32, i32* %19
%291 = add nsw i32 %290, 1
store i32 %291, i32* %19
br label %252
292: ; preds = %252
br label %293
293: ; preds = %297, %292
%294 = load i32, i32* %18
%295 = load i32, i32* %8
%296 = icmp slt i32 %294, %295
br i1 %296, label %297, label %333
297: ; preds = %293
%298 = load double, double* %11
%299 = load double*, double** %9
%300 = load i32, i32* %18
%301 = sext i32 %300 to i64
%302 = getelementptr inbounds double, double* %299, i64 %301
%303 = load double, double* %302
%304 = fadd double %298, %303
store double %304, double* %12
%305 = load double, double* %12
%306 = load double, double* %11
%307 = fsub double %305, %306
store double %307, double* %13
%308 = load double, double* %12
%309 = load double, double* %13
%310 = fsub double %308, %309
store double %310, double* %14
%311 = load double*, double** %9
%312 = load i32, i32* %18
%313 = sext i32 %312 to i64
%314 = getelementptr inbounds double, double* %311, i64 %313
%315 = load double, double* %314
%316 = load double, double* %13
%317 = fsub double %315, %316
store double %317, double* %15
%318 = load double, double* %11
%319 = load double, double* %14
%320 = fsub double %318, %319
store double %320, double* %16
%321 = load double, double* %16
%322 = load double, double* %15
%323 = fadd double %321, %322
%324 = load double*, double** %10
%325 = load i32, i32* %19
%326 = sext i32 %325 to i64
%327 = getelementptr inbounds double, double* %324, i64 %326
store double %323, double* %327
%328 = load i32, i32* %18
%329 = add nsw i32 %328, 1
store i32 %329, i32* %18
%330 = load double, double* %12
store double %330, double* %11
%331 = load i32, i32* %19
%332 = add nsw i32 %331, 1
store i32 %332, i32* %19
br label %293
333: ; preds = %293
%334 = load double, double* %11
%335 = load double*, double** %10
%336 = load i32, i32* %19
%337 = sext i32 %336 to i64
%338 = getelementptr inbounds double, double* %335, i64 %337
store double %334, double* %338
%339 = load i32, i32* %19
%340 = add nsw i32 %339, 1
ret i32 %340
}

LLVM IR (-O2):
define i32 @fast_expansion_sum(i32 %0, double* nocapture %1, i32 %2, double* nocapture %3, double* nocapture writeonly %4) {
%6 = load double, double* %3
%7 = load double, double* %1
%8 = fcmp ule double %6, %7
%9 = fneg double %7
%10 = fcmp ogt double %6, %9
%11 = xor i1 %8, %10
%12 = select i1 %11, double %7, double %6
%13 = zext i1 %11 to i32
%14 = xor i1 %11, true
%15 = zext i1 %14 to i32
%16 = icmp slt i32 %13, %0
%17 = icmp slt i32 %15, %2
%18 = and i1 %16, %17
br i1 %18, label %19, label %90
19: ; preds = %5
%20 = zext i1 %14 to i64
%21 = getelementptr inbounds double, double* %3, i64 %20
%22 = load double, double* %21
%23 = zext i1 %11 to i64
%24 = getelementptr inbounds double, double* %1, i64 %23
%25 = load double, double* %24
%26 = fcmp ule double %22, %25
%27 = fneg double %25
%28 = fcmp ogt double %22, %27
%29 = xor i1 %26, %28
br i1 %29, label %30, label %35
30: ; preds = %19
%31 = fadd double %12, %25
%32 = fsub double %31, %25
%33 = fsub double %12, %32
store double %33, double* %4
%34 = select i1 %11, i32 2, i32 1
br label %40
35: ; preds = %19
%36 = fadd double %12, %22
%37 = fsub double %36, %22
%38 = fsub double %12, %37
store double %38, double* %4
%39 = select i1 %11, i32 1, i32 2
br label %40
40: ; preds = %35, %30
%41 = phi double [ %31, %30 ], [ %36, %35 ]
%42 = phi i32 [ %34, %30 ], [ %13, %35 ]
%43 = phi i32 [ %15, %30 ], [ %39, %35 ]
%44 = icmp slt i32 %42, %0
%45 = icmp slt i32 %43, %2
%46 = select i1 %44, i1 %45, i1 false
br i1 %46, label %47, label %90
47: ; preds = %40, %78
%48 = phi i64 [ %84, %78 ], [ 1, %40 ]
%49 = phi i32 [ %82, %78 ], [ %43, %40 ]
%50 = phi i32 [ %81, %78 ], [ %42, %40 ]
%51 = phi double [ %80, %78 ], [ %41, %40 ]
%52 = sext i32 %49 to i64
%53 = getelementptr inbounds double, double* %3, i64 %52
%54 = load double, double* %53
%55 = sext i32 %50 to i64
%56 = getelementptr inbounds double, double* %1, i64 %55
%57 = load double, double* %56
%58 = fcmp ule double %54, %57
%59 = fneg double %57
%60 = fcmp ogt double %54, %59
%61 = xor i1 %58, %60
br i1 %61, label %62, label %70
62: ; preds = %47
%63 = fadd double %51, %57
%64 = fsub double %63, %51
%65 = fsub double %63, %64
%66 = fsub double %57, %64
%67 = fsub double %51, %65
%68 = fadd double %66, %67
%69 = add nsw i32 %50, 1
br label %78
70: ; preds = %47
%71 = fadd double %51, %54
%72 = fsub double %71, %51
%73 = fsub double %71, %72
%74 = fsub double %54, %72
%75 = fsub double %51, %73
%76 = fadd double %74, %75
%77 = add nsw i32 %49, 1
br label %78
78: ; preds = %70, %62
%79 = phi double [ %68, %62 ], [ %76, %70 ]
%80 = phi double [ %63, %62 ], [ %71, %70 ]
%81 = phi i32 [ %69, %62 ], [ %50, %70 ]
%82 = phi i32 [ %49, %62 ], [ %77, %70 ]
%83 = getelementptr inbounds double, double* %4, i64 %48
store double %79, double* %83
%84 = add nuw i64 %48, 1
%85 = icmp slt i32 %81, %0
%86 = icmp slt i32 %82, %2
%87 = select i1 %85, i1 %86, i1 false
br i1 %87, label %47, label %88
88: ; preds = %78
%89 = trunc i64 %84 to i32
br label %90
90: ; preds = %88, %40, %5
%91 = phi double [ %12, %5 ], [ %41, %40 ], [ %80, %88 ]
%92 = phi i32 [ %13, %5 ], [ %42, %40 ], [ %81, %88 ]
%93 = phi i32 [ %15, %5 ], [ %43, %40 ], [ %82, %88 ]
%94 = phi i32 [ 0, %5 ], [ 1, %40 ], [ %89, %88 ]
%95 = icmp slt i32 %92, %0
br i1 %95, label %96, label %128
96: ; preds = %90
%97 = zext i32 %94 to i64
%98 = sext i32 %92 to i64
%99 = sext i32 %0 to i64
%100 = sub nsw i64 %99, %98
%101 = xor i64 %98, -1
%102 = and i64 %100, 1
%103 = icmp eq i64 %102, 0
br i1 %103, label %116, label %104
104: ; preds = %96
%105 = getelementptr inbounds double, double* %1, i64 %98
%106 = load double, double* %105
%107 = fadd double %91, %106
%108 = fsub double %107, %91
%109 = fsub double %107, %108
%110 = fsub double %106, %108
%111 = fsub double %91, %109
%112 = fadd double %110, %111
%113 = getelementptr inbounds double, double* %4, i64 %97
store double %112, double* %113
%114 = add nsw i64 %98, 1
%115 = add nuw nsw i64 %97, 1
br label %116
116: ; preds = %104, %96
%117 = phi double [ undef, %96 ], [ %107, %104 ]
%118 = phi i64 [ undef, %96 ], [ %115, %104 ]
%119 = phi i64 [ %98, %96 ], [ %114, %104 ]
%120 = phi i64 [ %97, %96 ], [ %115, %104 ]
%121 = phi double [ %91, %96 ], [ %107, %104 ]
%122 = sub nsw i64 0, %99
%123 = icmp eq i64 %101, %122
br i1 %123, label %124, label %160
124: ; preds = %160, %116
%125 = phi double [ %117, %116 ], [ %177, %160 ]
%126 = phi i64 [ %118, %116 ], [ %185, %160 ]
%127 = trunc i64 %126 to i32
br label %128
128: ; preds = %124, %90
%129 = phi double [ %91, %90 ], [ %125, %124 ]
%130 = phi i32 [ %94, %90 ], [ %127, %124 ]
%131 = icmp slt i32 %93, %2
br i1 %131, label %132, label %218
132: ; preds = %128
%133 = zext i32 %130 to i64
%134 = sext i32 %93 to i64
%135 = sext i32 %2 to i64
%136 = sub nsw i64 %135, %134
%137 = xor i64 %134, -1
%138 = and i64 %136, 1
%139 = icmp eq i64 %138, 0
br i1 %139, label %152, label %140
140: ; preds = %132
%141 = getelementptr inbounds double, double* %3, i64 %134
%142 = load double, double* %141
%143 = fadd double %129, %142
%144 = fsub double %143, %129
%145 = fsub double %143, %144
%146 = fsub double %142, %144
%147 = fsub double %129, %145
%148 = fadd double %146, %147
%149 = getelementptr inbounds double, double* %4, i64 %133
store double %148, double* %149
%150 = add nsw i64 %134, 1
%151 = add nuw nsw i64 %133, 1
br label %152
152: ; preds = %140, %132
%153 = phi double [ undef, %132 ], [ %143, %140 ]
%154 = phi i64 [ undef, %132 ], [ %151, %140 ]
%155 = phi i64 [ %134, %132 ], [ %150, %140 ]
%156 = phi i64 [ %133, %132 ], [ %151, %140 ]
%157 = phi double [ %129, %132 ], [ %143, %140 ]
%158 = sub nsw i64 0, %135
%159 = icmp eq i64 %137, %158
br i1 %159, label %214, label %187
160: ; preds = %116, %160
%161 = phi i64 [ %184, %160 ], [ %119, %116 ]
%162 = phi i64 [ %185, %160 ], [ %120, %116 ]
%163 = phi double [ %177, %160 ], [ %121, %116 ]
%164 = getelementptr inbounds double, double* %1, i64 %161
%165 = load double, double* %164
%166 = fadd double %163, %165
%167 = fsub double %166, %163
%168 = fsub double %166, %167
%169 = fsub double %165, %167
%170 = fsub double %163, %168
%171 = fadd double %169, %170
%172 = getelementptr inbounds double, double* %4, i64 %162
store double %171, double* %172
%173 = add nsw i64 %161, 1
%174 = add nuw nsw i64 %162, 1
%175 = getelementptr inbounds double, double* %1, i64 %173
%176 = load double, double* %175
%177 = fadd double %166, %176
%178 = fsub double %177, %166
%179 = fsub double %177, %178
%180 = fsub double %176, %178
%181 = fsub double %166, %179
%182 = fadd double %180, %181
%183 = getelementptr inbounds double, double* %4, i64 %174
store double %182, double* %183
%184 = add nsw i64 %161, 2
%185 = add nuw nsw i64 %162, 2
%186 = icmp eq i64 %184, %99
br i1 %186, label %124, label %160
187: ; preds = %152, %187
%188 = phi i64 [ %211, %187 ], [ %155, %152 ]
%189 = phi i64 [ %212, %187 ], [ %156, %152 ]
%190 = phi double [ %204, %187 ], [ %157, %152 ]
%191 = getelementptr inbounds double, double* %3, i64 %188
%192 = load double, double* %191
%193 = fadd double %190, %192
%194 = fsub double %193, %190
%195 = fsub double %193, %194
%196 = fsub double %192, %194
%197 = fsub double %190, %195
%198 = fadd double %196, %197
%199 = getelementptr inbounds double, double* %4, i64 %189
store double %198, double* %199
%200 = add nsw i64 %188, 1
%201 = add nuw nsw i64 %189, 1
%202 = getelementptr inbounds double, double* %3, i64 %200
%203 = load double, double* %202
%204 = fadd double %193, %203
%205 = fsub double %204, %193
%206 = fsub double %204, %205
%207 = fsub double %203, %205
%208 = fsub double %193, %206
%209 = fadd double %207, %208
%210 = getelementptr inbounds double, double* %4, i64 %201
store double %209, double* %210
%211 = add nsw i64 %188, 2
%212 = add nuw nsw i64 %189, 2
%213 = icmp eq i64 %211, %135
br i1 %213, label %214, label %187
214: ; preds = %187, %152
%215 = phi double [ %153, %152 ], [ %204, %187 ]
%216 = phi i64 [ %154, %152 ], [ %212, %187 ]
%217 = trunc i64 %216 to i32
br label %218
218: ; preds = %214, %128
%219 = phi double [ %129, %128 ], [ %215, %214 ]
%220 = phi i32 [ %130, %128 ], [ %217, %214 ]
%221 = zext i32 %220 to i64
%222 = getelementptr inbounds double, double* %4, i64 %221
store double %219, double* %222
%223 = add nuw nsw i32 %220, 1
ret i32 %223
}