int sumVec(double c[], double ca, double a[], double cb, double b[], int n) {
  int i;
  for (i = n; i-- > 0;)
    c[i] = ca * a[i] + cb * b[i];
  return 0;
}


x86 assembly (clang, -O0):
<sumVec>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %rdx,-0x28(%rbp)
mov    %ecx,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x30(%rbp)
cmp    $0x0,%eax
jle    1175 <sumVec+0x75>
movsd  -0x10(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x20(%rbp),%xmm1
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x30(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    1123 <sumVec+0x23>
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sumVec>:
push   %r15
push   %r14
push   %rbx
test   %ecx,%ecx
jle    1258 <sumVec+0x158>
mov    %ecx,%r8d
cmp    $0x4,%ecx
jb     1222 <sumVec+0x122>
lea    -0x1(%r8),%r10
add    $0xffffffff,%ecx
cmp    %r10d,%ecx
jb     1222 <sumVec+0x122>
mov    %r10,%rax
shr    $0x20,%rax
jne    1222 <sumVec+0x122>
mov    %r8,%rax
neg    %rax
add    %rcx,%rax
add    $0x1,%rax
lea    (%rdi,%rax,8),%r9
lea    0x8(%rdi,%rcx,8),%r11
lea    (%rsi,%rax,8),%r14
lea    (%rsi,%rcx,8),%rbx
add    $0x8,%rbx
lea    (%rdx,%rax,8),%r15
lea    (%rdx,%rcx,8),%rax
add    $0x8,%rax
cmp    %rbx,%r9
setb   %bl
cmp    %r11,%r14
setb   %cl
cmp    %rax,%r9
setb   %al
cmp    %r11,%r15
setb   %r9b
test   %cl,%bl
jne    1222 <sumVec+0x122>
and    %r9b,%al
jne    1222 <sumVec+0x122>
mov    %r8d,%r9d
and    $0xfffffffc,%r9d
mov    %r8d,%ecx
and    $0x3,%ecx
movapd %xmm1,%xmm2
unpcklpd %xmm1,%xmm2
movapd %xmm0,%xmm3
unpcklpd %xmm0,%xmm3
mov    %r9,%r11
xchg   %ax,%ax
mov    %r10d,%eax
shl    $0x3,%rax
movupd -0x18(%rsi,%rax,1),%xmm4
movupd -0x8(%rsi,%rax,1),%xmm5
shufpd $0x1,%xmm5,%xmm5
shufpd $0x1,%xmm4,%xmm4
movupd -0x18(%rdx,%rax,1),%xmm6
movupd -0x8(%rdx,%rax,1),%xmm7
shufpd $0x1,%xmm7,%xmm7
shufpd $0x1,%xmm6,%xmm6
mulpd  %xmm2,%xmm7
mulpd  %xmm2,%xmm6
mulpd  %xmm3,%xmm5
addpd  %xmm7,%xmm5
mulpd  %xmm3,%xmm4
addpd  %xmm6,%xmm4
shufpd $0x1,%xmm5,%xmm5
movupd %xmm5,-0x8(%rdi,%rax,1)
shufpd $0x1,%xmm4,%xmm4
movupd %xmm4,-0x18(%rdi,%rax,1)
add    $0xfffffffffffffffc,%r10
add    $0xfffffffffffffffc,%r11
jne    11b0 <sumVec+0xb0>
cmp    %r8,%r9
jne    1225 <sumVec+0x125>
jmp    1258 <sumVec+0x158>
mov    %r8,%rcx
add    $0x1,%rcx
nopl   0x0(%rax)
lea    -0x2(%rcx),%eax
movsd  (%rdx,%rax,8),%xmm2
mulsd  %xmm1,%xmm2
movsd  (%rsi,%rax,8),%xmm3
mulsd  %xmm0,%xmm3
addsd  %xmm2,%xmm3
movsd  %xmm3,(%rdi,%rax,8)
add    $0xffffffffffffffff,%rcx
cmp    $0x1,%rcx
ja     1230 <sumVec+0x130>
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i32 @sumVec(double* %0, double %1, double* %2, double %3, double* %4, i32 %5) {
%7 = alloca double*
%8 = alloca double
%9 = alloca double*
%10 = alloca double
%11 = alloca double*
%12 = alloca i32
%13 = alloca i32
store double* %0, double** %7
store double %1, double* %8
store double* %2, double** %9
store double %3, double* %10
store double* %4, double** %11
store i32 %5, i32* %12
%14 = load i32, i32* %12
store i32 %14, i32* %13
br label %15
15: ; preds = %19, %6
%16 = load i32, i32* %13
%17 = add nsw i32 %16, -1
store i32 %17, i32* %13
%18 = icmp sgt i32 %16, 0
br i1 %18, label %19, label %38
19: ; preds = %15
%20 = load double, double* %8
%21 = load double*, double** %9
%22 = load i32, i32* %13
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds double, double* %21, i64 %23
%25 = load double, double* %24
%26 = load double, double* %10
%27 = load double*, double** %11
%28 = load i32, i32* %13
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds double, double* %27, i64 %29
%31 = load double, double* %30
%32 = fmul double %26, %31
%33 = call double @llvm.fmuladd.f64(double %20, double %25, double %32)
%34 = load double*, double** %7
%35 = load i32, i32* %13
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds double, double* %34, i64 %36
store double %33, double* %37
br label %15
38: ; preds = %15
ret i32 0
}

LLVM IR (-O2):
define i32 @sumVec(double* nocapture writeonly %0, double %1, double* nocapture %2, double %3, double* nocapture %4, i32 %5) {
%7 = icmp sgt i32 %5, 0
br i1 %7, label %8, label %103
8: ; preds = %6
%9 = zext i32 %5 to i64
%10 = icmp ult i32 %5, 4
br i1 %10, label %89, label %11
11: ; preds = %8
%12 = add nsw i64 %9, -1
%13 = add i32 %5, -1
%14 = trunc i64 %12 to i32
%15 = icmp ult i32 %13, %14
%16 = icmp ugt i64 %12, 4294967295
%17 = or i1 %15, %16
br i1 %17, label %89, label %18
18: ; preds = %11
%19 = add i32 %5, -1
%20 = zext i32 %19 to i64
%21 = add nuw nsw i64 %20, 1
%22 = sub nsw i64 %21, %9
%23 = getelementptr double, double* %0, i64 %22
%24 = add nuw nsw i64 %20, 1
%25 = getelementptr double, double* %0, i64 %24
%26 = getelementptr double, double* %2, i64 %22
%27 = getelementptr double, double* %2, i64 %24
%28 = getelementptr double, double* %4, i64 %22
%29 = getelementptr double, double* %4, i64 %24
%30 = icmp ult double* %23, %27
%31 = icmp ult double* %26, %25
%32 = and i1 %30, %31
%33 = icmp ult double* %23, %29
%34 = icmp ult double* %28, %25
%35 = and i1 %33, %34
%36 = or i1 %32, %35
br i1 %36, label %89, label %37
37: ; preds = %18
%38 = and i64 %9, 4294967292
%39 = and i64 %9, 3
%40 = insertelement <2 x double> poison, double %3, i64 0
%41 = shufflevector <2 x double> %40, <2 x double> poison, <2 x i32> zeroinitializer
%42 = insertelement <2 x double> poison, double %3, i64 0
%43 = shufflevector <2 x double> %42, <2 x double> poison, <2 x i32> zeroinitializer
%44 = insertelement <2 x double> poison, double %1, i64 0
%45 = shufflevector <2 x double> %44, <2 x double> poison, <2 x i32> zeroinitializer
%46 = insertelement <2 x double> poison, double %1, i64 0
%47 = shufflevector <2 x double> %46, <2 x double> poison, <2 x i32> zeroinitializer
br label %48
48: ; preds = %48, %37
%49 = phi i64 [ 0, %37 ], [ %85, %48 ]
%50 = xor i64 %49, -1
%51 = add i64 %50, %9
%52 = and i64 %51, 4294967295
%53 = getelementptr inbounds double, double* %2, i64 %52
%54 = getelementptr inbounds double, double* %53, i64 -1
%55 = bitcast double* %54 to <2 x double>*
%56 = load <2 x double>, <2 x double>* %55
%57 = shufflevector <2 x double> %56, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%58 = getelementptr inbounds double, double* %53, i64 -2
%59 = getelementptr inbounds double, double* %58, i64 -1
%60 = bitcast double* %59 to <2 x double>*
%61 = load <2 x double>, <2 x double>* %60
%62 = shufflevector <2 x double> %61, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%63 = getelementptr inbounds double, double* %4, i64 %52
%64 = getelementptr inbounds double, double* %63, i64 -1
%65 = bitcast double* %64 to <2 x double>*
%66 = load <2 x double>, <2 x double>* %65
%67 = shufflevector <2 x double> %66, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%68 = getelementptr inbounds double, double* %63, i64 -2
%69 = getelementptr inbounds double, double* %68, i64 -1
%70 = bitcast double* %69 to <2 x double>*
%71 = load <2 x double>, <2 x double>* %70
%72 = shufflevector <2 x double> %71, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%73 = fmul <2 x double> %67, %41
%74 = fmul <2 x double> %72, %43
%75 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %45, <2 x double> %57, <2 x double> %73)
%76 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %47, <2 x double> %62, <2 x double> %74)
%77 = getelementptr inbounds double, double* %0, i64 %52
%78 = shufflevector <2 x double> %75, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%79 = getelementptr inbounds double, double* %77, i64 -1
%80 = bitcast double* %79 to <2 x double>*
store <2 x double> %78, <2 x double>* %80
%81 = shufflevector <2 x double> %76, <2 x double> poison, <2 x i32> <i32 1, i32 0>
%82 = getelementptr inbounds double, double* %77, i64 -2
%83 = getelementptr inbounds double, double* %82, i64 -1
%84 = bitcast double* %83 to <2 x double>*
store <2 x double> %81, <2 x double>* %84
%85 = add nuw i64 %49, 4
%86 = icmp eq i64 %85, %38
br i1 %86, label %87, label %48
87: ; preds = %48
%88 = icmp eq i64 %38, %9
br i1 %88, label %103, label %89
89: ; preds = %18, %11, %8, %87
%90 = phi i64 [ %9, %18 ], [ %9, %11 ], [ %9, %8 ], [ %39, %87 ]
br label %91
91: ; preds = %89, %91
%92 = phi i64 [ %93, %91 ], [ %90, %89 ]
%93 = add nsw i64 %92, -1
%94 = and i64 %93, 4294967295
%95 = getelementptr inbounds double, double* %2, i64 %94
%96 = load double, double* %95
%97 = getelementptr inbounds double, double* %4, i64 %94
%98 = load double, double* %97
%99 = fmul double %98, %3
%100 = tail call double @llvm.fmuladd.f64(double %1, double %96, double %99)
%101 = getelementptr inbounds double, double* %0, i64 %94
store double %100, double* %101
%102 = icmp ugt i64 %92, 1
br i1 %102, label %91, label %103
103: ; preds = %91, %87, %6
ret i32 0
}