void psum1a(float a[], float p[], long n) {
  long i;
  float last_val, val;
  last_val = p[0] = a[0];
  for (i = 1; i < n; i++) {
    val = last_val + a[i];
    p[i] = val;
    last_val = val;
  }
}


x86 assembly (clang, -O0):
<psum1a>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movss  %xmm0,-0x24(%rbp)
movq   $0x1,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    117f <psum1a+0x7f>
movss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
addss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x28(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    112d <psum1a+0x2d>
pop    %rbp
ret

x86 assembly (clang, -O2):
<psum1a>:
movss  (%rdi),%xmm0
movss  %xmm0,(%rsi)
cmp    $0x2,%rdx
jl     11a3 <psum1a+0xa3>
lea    -0x1(%rdx),%rax
add    $0xfffffffffffffffe,%rdx
mov    %eax,%r8d
and    $0x3,%r8d
mov    $0x1,%ecx
cmp    $0x3,%rdx
jb     117d <psum1a+0x7d>
and    $0xfffffffffffffffc,%rax
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
addss  0x4(%rdi,%rcx,4),%xmm0
movss  %xmm0,0x4(%rsi,%rcx,4)
addss  0x8(%rdi,%rcx,4),%xmm0
movss  %xmm0,0x8(%rsi,%rcx,4)
addss  0xc(%rdi,%rcx,4),%xmm0
movss  %xmm0,0xc(%rsi,%rcx,4)
addss  0x10(%rdi,%rcx,4),%xmm0
movss  %xmm0,0x10(%rsi,%rcx,4)
add    $0x4,%rcx
cmp    %rcx,%rax
jne    1140 <psum1a+0x40>
add    $0x1,%rcx
test   %r8,%r8
je     11a3 <psum1a+0xa3>
lea    (%rsi,%rcx,4),%rax
lea    (%rdi,%rcx,4),%rcx
xor    %edx,%edx
nopl   0x0(%rax)
addss  (%rcx,%rdx,4),%xmm0
movss  %xmm0,(%rax,%rdx,4)
add    $0x1,%rdx
cmp    %rdx,%r8
jne    1190 <psum1a+0x90>
ret

LLVM IR (-O0):
define void @psum1a(float* %0, float* %1, i64 %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca i64
%7 = alloca i64
%8 = alloca float
%9 = alloca float
store float* %0, float** %4
store float* %1, float** %5
store i64 %2, i64* %6
%10 = load float*, float** %4
%11 = getelementptr inbounds float, float* %10, i64 0
%12 = load float, float* %11
%13 = load float*, float** %5
%14 = getelementptr inbounds float, float* %13, i64 0
store float %12, float* %14
store float %12, float* %8
store i64 1, i64* %7
br label %15
15: ; preds = %31, %3
%16 = load i64, i64* %7
%17 = load i64, i64* %6
%18 = icmp slt i64 %16, %17
br i1 %18, label %19, label %34
19: ; preds = %15
%20 = load float, float* %8
%21 = load float*, float** %4
%22 = load i64, i64* %7
%23 = getelementptr inbounds float, float* %21, i64 %22
%24 = load float, float* %23
%25 = fadd float %20, %24
store float %25, float* %9
%26 = load float, float* %9
%27 = load float*, float** %5
%28 = load i64, i64* %7
%29 = getelementptr inbounds float, float* %27, i64 %28
store float %26, float* %29
%30 = load float, float* %9
store float %30, float* %8
br label %31
31: ; preds = %19
%32 = load i64, i64* %7
%33 = add nsw i64 %32, 1
store i64 %33, i64* %7
br label %15
34: ; preds = %15
ret void
}

LLVM IR (-O2):
define void @psum1a(float* nocapture %0, float* nocapture writeonly %1, i64 %2) {
%4 = load float, float* %0
store float %4, float* %1
%5 = icmp sgt i64 %2, 1
br i1 %5, label %6, label %54
6: ; preds = %3
%7 = add i64 %2, -1
%8 = add i64 %2, -2
%9 = and i64 %7, 3
%10 = icmp ult i64 %8, 3
br i1 %10, label %39, label %11
11: ; preds = %6
%12 = and i64 %7, -4
br label %13
13: ; preds = %13, %11
%14 = phi i64 [ 1, %11 ], [ %36, %13 ]
%15 = phi float [ %4, %11 ], [ %34, %13 ]
%16 = phi i64 [ 0, %11 ], [ %37, %13 ]
%17 = getelementptr inbounds float, float* %0, i64 %14
%18 = load float, float* %17
%19 = fadd float %15, %18
%20 = getelementptr inbounds float, float* %1, i64 %14
store float %19, float* %20
%21 = add nuw nsw i64 %14, 1
%22 = getelementptr inbounds float, float* %0, i64 %21
%23 = load float, float* %22
%24 = fadd float %19, %23
%25 = getelementptr inbounds float, float* %1, i64 %21
store float %24, float* %25
%26 = add nuw nsw i64 %14, 2
%27 = getelementptr inbounds float, float* %0, i64 %26
%28 = load float, float* %27
%29 = fadd float %24, %28
%30 = getelementptr inbounds float, float* %1, i64 %26
store float %29, float* %30
%31 = add nuw nsw i64 %14, 3
%32 = getelementptr inbounds float, float* %0, i64 %31
%33 = load float, float* %32
%34 = fadd float %29, %33
%35 = getelementptr inbounds float, float* %1, i64 %31
store float %34, float* %35
%36 = add nuw nsw i64 %14, 4
%37 = add i64 %16, 4
%38 = icmp eq i64 %37, %12
br i1 %38, label %39, label %13
39: ; preds = %13, %6
%40 = phi i64 [ 1, %6 ], [ %36, %13 ]
%41 = phi float [ %4, %6 ], [ %34, %13 ]
%42 = icmp eq i64 %9, 0
br i1 %42, label %54, label %43
43: ; preds = %39, %43
%44 = phi i64 [ %51, %43 ], [ %40, %39 ]
%45 = phi float [ %49, %43 ], [ %41, %39 ]
%46 = phi i64 [ %52, %43 ], [ 0, %39 ]
%47 = getelementptr inbounds float, float* %0, i64 %44
%48 = load float, float* %47
%49 = fadd float %45, %48
%50 = getelementptr inbounds float, float* %1, i64 %44
store float %49, float* %50
%51 = add nuw nsw i64 %44, 1
%52 = add i64 %46, 1
%53 = icmp eq i64 %52, %9
br i1 %53, label %54, label %43
54: ; preds = %39, %43, %3
ret void
}