void mvp_alpha3x3(double alpha, const double *restrict a,
                  const double *restrict v, double *restrict r) {
  double *pr;
  pr = r;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v++;
  pr = r;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v++;
  pr = r;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v;
  *pr++ += alpha * *a++ * *v++;
}


x86 assembly (clang, -O0):
<mvp_alpha3x3>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x18(%rbp)
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
mov    %rax,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x18(%rbp)
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
mov    %rax,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
mulsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x18(%rbp)
movsd  (%rax),%xmm2
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x28(%rbp)
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<mvp_alpha3x3>:
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
movupd (%rdi),%xmm4
movupd 0x18(%rdi),%xmm3
movupd 0x30(%rdi),%xmm2
mulpd  %xmm1,%xmm4
movupd (%rdx),%xmm8
movsd  (%rsi),%xmm6
movsd  0x8(%rsi),%xmm7
movsd  0x10(%rdi),%xmm5
mulsd  %xmm0,%xmm5
mulsd  %xmm6,%xmm5
unpcklpd %xmm6,%xmm6
mulpd  %xmm4,%xmm6
addsd  0x10(%rdx),%xmm5
addpd  %xmm8,%xmm6
mulpd  %xmm1,%xmm3
movsd  0x28(%rdi),%xmm4
mulsd  %xmm0,%xmm4
mulsd  %xmm7,%xmm4
unpcklpd %xmm7,%xmm7
mulpd  %xmm3,%xmm7
addpd  %xmm6,%xmm7
addsd  %xmm5,%xmm4
movsd  0x10(%rsi),%xmm3
mulsd  0x40(%rdi),%xmm0
mulpd  %xmm1,%xmm2
mulsd  %xmm3,%xmm0
unpcklpd %xmm3,%xmm3
mulpd  %xmm2,%xmm3
addpd  %xmm7,%xmm3
movupd %xmm3,(%rdx)
addsd  %xmm4,%xmm0
movsd  %xmm0,0x10(%rdx)
ret

LLVM IR (-O0):
define void @mvp_alpha3x3(double %0, double* noalias %1, double* noalias %2, double* noalias %3) {
%5 = alloca double
%6 = alloca double*
%7 = alloca double*
%8 = alloca double*
%9 = alloca double*
store double %0, double* %5
store double* %1, double** %6
store double* %2, double** %7
store double* %3, double** %8
%10 = load double*, double** %8
store double* %10, double** %9
%11 = load double, double* %5
%12 = load double*, double** %6
%13 = getelementptr inbounds double, double* %12, i32 1
store double* %13, double** %6
%14 = load double, double* %12
%15 = fmul double %11, %14
%16 = load double*, double** %7
%17 = load double, double* %16
%18 = load double*, double** %9
%19 = getelementptr inbounds double, double* %18, i32 1
store double* %19, double** %9
%20 = load double, double* %18
%21 = call double @llvm.fmuladd.f64(double %15, double %17, double %20)
store double %21, double* %18
%22 = load double, double* %5
%23 = load double*, double** %6
%24 = getelementptr inbounds double, double* %23, i32 1
store double* %24, double** %6
%25 = load double, double* %23
%26 = fmul double %22, %25
%27 = load double*, double** %7
%28 = load double, double* %27
%29 = load double*, double** %9
%30 = getelementptr inbounds double, double* %29, i32 1
store double* %30, double** %9
%31 = load double, double* %29
%32 = call double @llvm.fmuladd.f64(double %26, double %28, double %31)
store double %32, double* %29
%33 = load double, double* %5
%34 = load double*, double** %6
%35 = getelementptr inbounds double, double* %34, i32 1
store double* %35, double** %6
%36 = load double, double* %34
%37 = fmul double %33, %36
%38 = load double*, double** %7
%39 = getelementptr inbounds double, double* %38, i32 1
store double* %39, double** %7
%40 = load double, double* %38
%41 = load double*, double** %9
%42 = getelementptr inbounds double, double* %41, i32 1
store double* %42, double** %9
%43 = load double, double* %41
%44 = call double @llvm.fmuladd.f64(double %37, double %40, double %43)
store double %44, double* %41
%45 = load double*, double** %8
store double* %45, double** %9
%46 = load double, double* %5
%47 = load double*, double** %6
%48 = getelementptr inbounds double, double* %47, i32 1
store double* %48, double** %6
%49 = load double, double* %47
%50 = fmul double %46, %49
%51 = load double*, double** %7
%52 = load double, double* %51
%53 = load double*, double** %9
%54 = getelementptr inbounds double, double* %53, i32 1
store double* %54, double** %9
%55 = load double, double* %53
%56 = call double @llvm.fmuladd.f64(double %50, double %52, double %55)
store double %56, double* %53
%57 = load double, double* %5
%58 = load double*, double** %6
%59 = getelementptr inbounds double, double* %58, i32 1
store double* %59, double** %6
%60 = load double, double* %58
%61 = fmul double %57, %60
%62 = load double*, double** %7
%63 = load double, double* %62
%64 = load double*, double** %9
%65 = getelementptr inbounds double, double* %64, i32 1
store double* %65, double** %9
%66 = load double, double* %64
%67 = call double @llvm.fmuladd.f64(double %61, double %63, double %66)
store double %67, double* %64
%68 = load double, double* %5
%69 = load double*, double** %6
%70 = getelementptr inbounds double, double* %69, i32 1
store double* %70, double** %6
%71 = load double, double* %69
%72 = fmul double %68, %71
%73 = load double*, double** %7
%74 = getelementptr inbounds double, double* %73, i32 1
store double* %74, double** %7
%75 = load double, double* %73
%76 = load double*, double** %9
%77 = getelementptr inbounds double, double* %76, i32 1
store double* %77, double** %9
%78 = load double, double* %76
%79 = call double @llvm.fmuladd.f64(double %72, double %75, double %78)
store double %79, double* %76
%80 = load double*, double** %8
store double* %80, double** %9
%81 = load double, double* %5
%82 = load double*, double** %6
%83 = getelementptr inbounds double, double* %82, i32 1
store double* %83, double** %6
%84 = load double, double* %82
%85 = fmul double %81, %84
%86 = load double*, double** %7
%87 = load double, double* %86
%88 = load double*, double** %9
%89 = getelementptr inbounds double, double* %88, i32 1
store double* %89, double** %9
%90 = load double, double* %88
%91 = call double @llvm.fmuladd.f64(double %85, double %87, double %90)
store double %91, double* %88
%92 = load double, double* %5
%93 = load double*, double** %6
%94 = getelementptr inbounds double, double* %93, i32 1
store double* %94, double** %6
%95 = load double, double* %93
%96 = fmul double %92, %95
%97 = load double*, double** %7
%98 = load double, double* %97
%99 = load double*, double** %9
%100 = getelementptr inbounds double, double* %99, i32 1
store double* %100, double** %9
%101 = load double, double* %99
%102 = call double @llvm.fmuladd.f64(double %96, double %98, double %101)
store double %102, double* %99
%103 = load double, double* %5
%104 = load double*, double** %6
%105 = getelementptr inbounds double, double* %104, i32 1
store double* %105, double** %6
%106 = load double, double* %104
%107 = fmul double %103, %106
%108 = load double*, double** %7
%109 = getelementptr inbounds double, double* %108, i32 1
store double* %109, double** %7
%110 = load double, double* %108
%111 = load double*, double** %9
%112 = getelementptr inbounds double, double* %111, i32 1
store double* %112, double** %9
%113 = load double, double* %111
%114 = call double @llvm.fmuladd.f64(double %107, double %110, double %113)
store double %114, double* %111
ret void
}

LLVM IR (-O2):
define void @mvp_alpha3x3(double %0, double* noalias nocapture %1, double* noalias nocapture %2, double* noalias nocapture %3) {
%5 = load double, double* %2
%6 = getelementptr inbounds double, double* %1, i64 2
%7 = bitcast double* %1 to <2 x double>*
%8 = load <2 x double>, <2 x double>* %7
%9 = insertelement <2 x double> poison, double %0, i64 0
%10 = shufflevector <2 x double> %9, <2 x double> poison, <2 x i32> zeroinitializer
%11 = fmul <2 x double> %8, %10
%12 = getelementptr inbounds double, double* %3, i64 2
%13 = bitcast double* %3 to <2 x double>*
%14 = load <2 x double>, <2 x double>* %13
%15 = insertelement <2 x double> poison, double %5, i64 0
%16 = shufflevector <2 x double> %15, <2 x double> poison, <2 x i32> zeroinitializer
%17 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %11, <2 x double> %16, <2 x double> %14)
%18 = getelementptr inbounds double, double* %1, i64 3
%19 = load double, double* %6
%20 = fmul double %19, %0
%21 = getelementptr inbounds double, double* %2, i64 1
%22 = load double, double* %12
%23 = tail call double @llvm.fmuladd.f64(double %20, double %5, double %22)
%24 = load double, double* %21
%25 = getelementptr inbounds double, double* %1, i64 5
%26 = bitcast double* %18 to <2 x double>*
%27 = load <2 x double>, <2 x double>* %26
%28 = fmul <2 x double> %27, %10
%29 = insertelement <2 x double> poison, double %24, i64 0
%30 = shufflevector <2 x double> %29, <2 x double> poison, <2 x i32> zeroinitializer
%31 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %28, <2 x double> %30, <2 x double> %17)
%32 = getelementptr inbounds double, double* %1, i64 6
%33 = load double, double* %25
%34 = fmul double %33, %0
%35 = getelementptr inbounds double, double* %2, i64 2
%36 = tail call double @llvm.fmuladd.f64(double %34, double %24, double %23)
%37 = load double, double* %35
%38 = getelementptr inbounds double, double* %1, i64 8
%39 = bitcast double* %32 to <2 x double>*
%40 = load <2 x double>, <2 x double>* %39
%41 = fmul <2 x double> %40, %10
%42 = insertelement <2 x double> poison, double %37, i64 0
%43 = shufflevector <2 x double> %42, <2 x double> poison, <2 x i32> zeroinitializer
%44 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %41, <2 x double> %43, <2 x double> %31)
%45 = bitcast double* %3 to <2 x double>*
store <2 x double> %44, <2 x double>* %45
%46 = load double, double* %38
%47 = fmul double %46, %0
%48 = tail call double @llvm.fmuladd.f64(double %47, double %37, double %36)
store double %48, double* %12
ret void
}