void mvm3x3(double *restrict a, double *restrict v, double *restrict r) {
  double *pr;
  pr = r;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v++;
  pr = r;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v++;
  pr = r;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v;
  *pr++ -= *a++ * *v++;
}


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

x86 assembly (clang, -O2):
<mvm3x3>:
movupd (%rdx),%xmm0
movsd  (%rsi),%xmm1
movsd  0x8(%rsi),%xmm2
movapd %xmm1,%xmm3
unpcklpd %xmm1,%xmm3
movupd (%rdi),%xmm4
mulpd  %xmm3,%xmm4
subpd  %xmm4,%xmm0
movupd 0x18(%rdi),%xmm3
movupd 0x30(%rdi),%xmm4
movsd  0x10(%rdx),%xmm5
mulsd  0x10(%rdi),%xmm1
subsd  %xmm1,%xmm5
movapd %xmm2,%xmm1
unpcklpd %xmm2,%xmm1
mulpd  %xmm3,%xmm1
subpd  %xmm1,%xmm0
mulsd  0x28(%rdi),%xmm2
subsd  %xmm2,%xmm5
movsd  0x10(%rsi),%xmm1
movapd %xmm1,%xmm2
unpcklpd %xmm1,%xmm2
mulpd  %xmm4,%xmm2
subpd  %xmm2,%xmm0
movupd %xmm0,(%rdx)
mulsd  0x40(%rdi),%xmm1
subsd  %xmm1,%xmm5
movsd  %xmm5,0x10(%rdx)
ret

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

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