void sum_pixels(float *p, const float *q0, const float *q1, const float *q2,
                const float *q3, int c) {
  switch (c) {
  case 4:
    p[3] = q0[3] + q1[3] + q2[3] + q3[3];
  case 3:
    p[2] = q0[2] + q1[2] + q2[2] + q3[2];
  case 2:
    p[1] = q0[1] + q1[1] + q2[1] + q3[1];
  case 1:
    p[0] = q0[0] + q1[0] + q2[0] + q3[0];
  }
}


x86 assembly (clang, -O0):
<sum_pixels>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9d,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x38(%rbp)
sub    $0x3,%eax
ja     11f4 <sum_pixels+0xf4>
mov    -0x38(%rbp),%rax
lea    0xec4(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
movss  0xc(%rax),%xmm0
mov    -0x18(%rbp),%rax
addss  0xc(%rax),%xmm0
mov    -0x20(%rbp),%rax
addss  0xc(%rax),%xmm0
mov    -0x28(%rbp),%rax
addss  0xc(%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
addss  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
addss  0x8(%rax),%xmm0
mov    -0x28(%rbp),%rax
addss  0x8(%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
addss  0x4(%rax),%xmm0
mov    -0x20(%rbp),%rax
addss  0x4(%rax),%xmm0
mov    -0x28(%rbp),%rax
addss  0x4(%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
addss  (%rax),%xmm0
mov    -0x20(%rbp),%rax
addss  (%rax),%xmm0
mov    -0x28(%rbp),%rax
addss  (%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<sum_pixels>:
add    $0xffffffff,%r9d
cmp    $0x3,%r9d
ja     117d <sum_pixels+0x7d>
lea    0xeef(%rip),%r10
movslq (%r10,%r9,4),%rax
add    %r10,%rax
jmp    *%rax
movss  0xc(%rsi),%xmm0
addss  0xc(%rdx),%xmm0
addss  0xc(%rcx),%xmm0
addss  0xc(%r8),%xmm0
movss  %xmm0,0xc(%rdi)
movss  0x8(%rsi),%xmm0
addss  0x8(%rdx),%xmm0
addss  0x8(%rcx),%xmm0
addss  0x8(%r8),%xmm0
movss  %xmm0,0x8(%rdi)
movss  0x4(%rsi),%xmm0
addss  0x4(%rdx),%xmm0
addss  0x4(%rcx),%xmm0
addss  0x4(%r8),%xmm0
movss  %xmm0,0x4(%rdi)
movss  (%rsi),%xmm0
addss  (%rdx),%xmm0
addss  (%rcx),%xmm0
addss  (%r8),%xmm0
movss  %xmm0,(%rdi)
ret

LLVM IR (-O0):
define void @sum_pixels(float* %0, float* %1, float* %2, float* %3, float* %4, i32 %5) {
%7 = alloca float*
%8 = alloca float*
%9 = alloca float*
%10 = alloca float*
%11 = alloca float*
%12 = alloca i32
store float* %0, float** %7
store float* %1, float** %8
store float* %2, float** %9
store float* %3, float** %10
store float* %4, float** %11
store i32 %5, i32* %12
%13 = load i32, i32* %12
switch i32 %13, label %86 [
i32 4, label %14
i32 3, label %32
i32 2, label %50
i32 1, label %68
]
14: ; preds = %6
%15 = load float*, float** %8
%16 = getelementptr inbounds float, float* %15, i64 3
%17 = load float, float* %16
%18 = load float*, float** %9
%19 = getelementptr inbounds float, float* %18, i64 3
%20 = load float, float* %19
%21 = fadd float %17, %20
%22 = load float*, float** %10
%23 = getelementptr inbounds float, float* %22, i64 3
%24 = load float, float* %23
%25 = fadd float %21, %24
%26 = load float*, float** %11
%27 = getelementptr inbounds float, float* %26, i64 3
%28 = load float, float* %27
%29 = fadd float %25, %28
%30 = load float*, float** %7
%31 = getelementptr inbounds float, float* %30, i64 3
store float %29, float* %31
br label %32
32: ; preds = %6, %14
%33 = load float*, float** %8
%34 = getelementptr inbounds float, float* %33, i64 2
%35 = load float, float* %34
%36 = load float*, float** %9
%37 = getelementptr inbounds float, float* %36, i64 2
%38 = load float, float* %37
%39 = fadd float %35, %38
%40 = load float*, float** %10
%41 = getelementptr inbounds float, float* %40, i64 2
%42 = load float, float* %41
%43 = fadd float %39, %42
%44 = load float*, float** %11
%45 = getelementptr inbounds float, float* %44, i64 2
%46 = load float, float* %45
%47 = fadd float %43, %46
%48 = load float*, float** %7
%49 = getelementptr inbounds float, float* %48, i64 2
store float %47, float* %49
br label %50
50: ; preds = %6, %32
%51 = load float*, float** %8
%52 = getelementptr inbounds float, float* %51, i64 1
%53 = load float, float* %52
%54 = load float*, float** %9
%55 = getelementptr inbounds float, float* %54, i64 1
%56 = load float, float* %55
%57 = fadd float %53, %56
%58 = load float*, float** %10
%59 = getelementptr inbounds float, float* %58, i64 1
%60 = load float, float* %59
%61 = fadd float %57, %60
%62 = load float*, float** %11
%63 = getelementptr inbounds float, float* %62, i64 1
%64 = load float, float* %63
%65 = fadd float %61, %64
%66 = load float*, float** %7
%67 = getelementptr inbounds float, float* %66, i64 1
store float %65, float* %67
br label %68
68: ; preds = %6, %50
%69 = load float*, float** %8
%70 = getelementptr inbounds float, float* %69, i64 0
%71 = load float, float* %70
%72 = load float*, float** %9
%73 = getelementptr inbounds float, float* %72, i64 0
%74 = load float, float* %73
%75 = fadd float %71, %74
%76 = load float*, float** %10
%77 = getelementptr inbounds float, float* %76, i64 0
%78 = load float, float* %77
%79 = fadd float %75, %78
%80 = load float*, float** %11
%81 = getelementptr inbounds float, float* %80, i64 0
%82 = load float, float* %81
%83 = fadd float %79, %82
%84 = load float*, float** %7
%85 = getelementptr inbounds float, float* %84, i64 0
store float %83, float* %85
br label %86
86: ; preds = %68, %6
ret void
}

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