int grow_expansion_zeroelim(int elen, double *e, double b, double *h) {
  double Q, hh;
  double Qnew;
  int eindex, hindex;
  double enow;
  double bvirt;
  double avirt, bround, around;
  hindex = 0;
  Q = b;
  for (eindex = 0; eindex < elen; eindex++) {
    enow = e[eindex];
    Qnew = (double)(Q + enow);
    bvirt = (double)(Qnew - Q);
    avirt = Qnew - bvirt;
    bround = enow - bvirt;
    around = Q - avirt;
    hh = around + bround;
    Q = Qnew;
    if (hh != 0.0) {
      h[hindex++] = hh;
    }
  }
  if ((Q != 0.0) || (hindex == 0)) {
    h[hindex++] = Q;
  }
  return hindex;
}


x86 assembly (clang, -O0):
<grow_expansion_zeroelim>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movl   $0x0,-0x40(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11fa <grow_expansion_zeroelim+0xfa>
mov    -0x10(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x38(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x48(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x28(%rbp),%xmm0
subsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x68(%rbp),%xmm0
addsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x30(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11cb <grow_expansion_zeroelim+0xcb>
jp     11cb <grow_expansion_zeroelim+0xcb>
jmp    11e7 <grow_expansion_zeroelim+0xe7>
movsd  -0x30(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x40(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x40(%rbp)
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    11ec <grow_expansion_zeroelim+0xec>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    112c <grow_expansion_zeroelim+0x2c>
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    121c <grow_expansion_zeroelim+0x11c>
jp     121c <grow_expansion_zeroelim+0x11c>
cmpl   $0x0,-0x40(%rbp)
jne    1238 <grow_expansion_zeroelim+0x138>
movsd  -0x28(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x40(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x40(%rbp)
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<grow_expansion_zeroelim>:
test   %edi,%edi
jle    1178 <grow_expansion_zeroelim+0x78>
mov    %edi,%r8d
xor    %edi,%edi
xorpd  %xmm1,%xmm1
xor    %eax,%eax
jmp    1129 <grow_expansion_zeroelim+0x29>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x1,%rdi
cmp    %rdi,%r8
je     1167 <grow_expansion_zeroelim+0x67>
movapd %xmm0,%xmm2
movsd  (%rsi,%rdi,8),%xmm3
addsd  %xmm3,%xmm0
movapd %xmm0,%xmm4
subsd  %xmm2,%xmm4
movapd %xmm0,%xmm5
subsd  %xmm4,%xmm5
subsd  %xmm4,%xmm3
subsd  %xmm5,%xmm2
addsd  %xmm3,%xmm2
ucomisd %xmm1,%xmm2
jne    115a <grow_expansion_zeroelim+0x5a>
jnp    1120 <grow_expansion_zeroelim+0x20>
movslq %eax,%rcx
add    $0x1,%eax
movsd  %xmm2,(%rdx,%rcx,8)
jmp    1120 <grow_expansion_zeroelim+0x20>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    117a <grow_expansion_zeroelim+0x7a>
jp     117a <grow_expansion_zeroelim+0x7a>
test   %eax,%eax
je     117a <grow_expansion_zeroelim+0x7a>
ret
xor    %eax,%eax
movslq %eax,%rcx
add    $0x1,%eax
movsd  %xmm0,(%rdx,%rcx,8)
ret

LLVM IR (-O0):
define i32 @grow_expansion_zeroelim(i32 %0, double* %1, double %2, double* %3) {
%5 = alloca i32
%6 = alloca double*
%7 = alloca double
%8 = alloca double*
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca i32
%13 = alloca i32
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
store i32 %0, i32* %5
store double* %1, double** %6
store double %2, double* %7
store double* %3, double** %8
store i32 0, i32* %13
%19 = load double, double* %7
store double %19, double* %9
store i32 0, i32* %12
br label %20
20: ; preds = %59, %4
%21 = load i32, i32* %12
%22 = load i32, i32* %5
%23 = icmp slt i32 %21, %22
br i1 %23, label %24, label %62
24: ; preds = %20
%25 = load double*, double** %6
%26 = load i32, i32* %12
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds double, double* %25, i64 %27
%29 = load double, double* %28
store double %29, double* %14
%30 = load double, double* %9
%31 = load double, double* %14
%32 = fadd double %30, %31
store double %32, double* %11
%33 = load double, double* %11
%34 = load double, double* %9
%35 = fsub double %33, %34
store double %35, double* %15
%36 = load double, double* %11
%37 = load double, double* %15
%38 = fsub double %36, %37
store double %38, double* %16
%39 = load double, double* %14
%40 = load double, double* %15
%41 = fsub double %39, %40
store double %41, double* %17
%42 = load double, double* %9
%43 = load double, double* %16
%44 = fsub double %42, %43
store double %44, double* %18
%45 = load double, double* %18
%46 = load double, double* %17
%47 = fadd double %45, %46
store double %47, double* %10
%48 = load double, double* %11
store double %48, double* %9
%49 = load double, double* %10
%50 = fcmp une double %49, 0.000000e+00
br i1 %50, label %51, label %58
51: ; preds = %24
%52 = load double, double* %10
%53 = load double*, double** %8
%54 = load i32, i32* %13
%55 = add nsw i32 %54, 1
store i32 %55, i32* %13
%56 = sext i32 %54 to i64
%57 = getelementptr inbounds double, double* %53, i64 %56
store double %52, double* %57
br label %58
58: ; preds = %51, %24
br label %59
59: ; preds = %58
%60 = load i32, i32* %12
%61 = add nsw i32 %60, 1
store i32 %61, i32* %12
br label %20
62: ; preds = %20
%63 = load double, double* %9
%64 = fcmp une double %63, 0.000000e+00
br i1 %64, label %68, label %65
65: ; preds = %62
%66 = load i32, i32* %13
%67 = icmp eq i32 %66, 0
br i1 %67, label %68, label %75
68: ; preds = %65, %62
%69 = load double, double* %9
%70 = load double*, double** %8
%71 = load i32, i32* %13
%72 = add nsw i32 %71, 1
store i32 %72, i32* %13
%73 = sext i32 %71 to i64
%74 = getelementptr inbounds double, double* %70, i64 %73
store double %69, double* %74
br label %75
75: ; preds = %68, %65
%76 = load i32, i32* %13
ret i32 %76
}

LLVM IR (-O2):
define i32 @grow_expansion_zeroelim(i32 %0, double* nocapture %1, double %2, double* nocapture writeonly %3) {
%5 = icmp sgt i32 %0, 0
br i1 %5, label %6, label %33
6: ; preds = %4
%7 = zext i32 %0 to i64
br label %8
8: ; preds = %6, %25
%9 = phi i64 [ 0, %6 ], [ %27, %25 ]
%10 = phi double [ %2, %6 ], [ %14, %25 ]
%11 = phi i32 [ 0, %6 ], [ %26, %25 ]
%12 = getelementptr inbounds double, double* %1, i64 %9
%13 = load double, double* %12
%14 = fadd double %10, %13
%15 = fsub double %14, %10
%16 = fsub double %14, %15
%17 = fsub double %13, %15
%18 = fsub double %10, %16
%19 = fadd double %17, %18
%20 = fcmp une double %19, 0.000000e+00
br i1 %20, label %21, label %25
21: ; preds = %8
%22 = add nsw i32 %11, 1
%23 = sext i32 %11 to i64
%24 = getelementptr inbounds double, double* %3, i64 %23
store double %19, double* %24
br label %25
25: ; preds = %8, %21
%26 = phi i32 [ %22, %21 ], [ %11, %8 ]
%27 = add nuw nsw i64 %9, 1
%28 = icmp eq i64 %27, %7
br i1 %28, label %29, label %8
29: ; preds = %25
%30 = fcmp une double %14, 0.000000e+00
%31 = icmp eq i32 %26, 0
%32 = select i1 %30, i1 true, i1 %31
br i1 %32, label %33, label %39
33: ; preds = %4, %29
%34 = phi double [ %14, %29 ], [ %2, %4 ]
%35 = phi i32 [ %26, %29 ], [ 0, %4 ]
%36 = add nsw i32 %35, 1
%37 = sext i32 %35 to i64
%38 = getelementptr inbounds double, double* %3, i64 %37
store double %34, double* %38
br label %39
39: ; preds = %29, %33
%40 = phi i32 [ %36, %33 ], [ %26, %29 ]
ret i32 %40
}