void mulmp(float *result, const float *s1, const float *s2) {
  const float x = s1[(0 + (0 << 2))] * s2[0] + s1[(0 + (1 << 2))] * s2[1] +
                  s1[(0 + (2 << 2))] * s2[2] + s1[(0 + (3 << 2))];
  const float y = s1[(1 + (0 << 2))] * s2[0] + s1[(1 + (1 << 2))] * s2[1] +
                  s1[(1 + (2 << 2))] * s2[2] + s1[(1 + (3 << 2))];
  const float z = s1[(2 + (0 << 2))] * s2[0] + s1[(2 + (1 << 2))] * s2[1] +
                  s1[(2 + (2 << 2))] * s2[2] + s1[(2 + (3 << 2))];
  const float w = s1[(3 + (0 << 2))] * s2[0] + s1[(3 + (1 << 2))] * s2[1] +
                  s1[(3 + (2 << 2))] * s2[2] + s1[(3 + (3 << 2))];
  if (w != 1) {
    const double l = 1 / (double)w;
    result[0] = (float)(x * l);
    result[1] = (float)(y * l);
    result[2] = (float)(z * l);
  } else {
    result[0] = x;
    result[1] = y;
    result[2] = z;
  }
}


x86 assembly (clang, -O0):
<mulmp>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x10(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x20(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
addss  0x30(%rax),%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x14(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x24(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
addss  0x34(%rax),%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x18(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x28(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
addss  0x38(%rax),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movss  0xc(%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x1c(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x2c(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
addss  0x3c(%rax),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x28(%rbp),%xmm0
movss  0xd98(%rip),%xmm1
ucomiss %xmm1,%xmm0
jne    127c <mulmp+0x17c>
jp     127c <mulmp+0x17c>
jmp    12eb <mulmp+0x1eb>
movss  -0x28(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd7b(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  -0x30(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x20(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  -0x30(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x24(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  -0x30(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
jmp    1314 <mulmp+0x214>
movss  -0x1c(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x20(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<mulmp>:
movss  (%rdx),%xmm7
movss  0x4(%rdx),%xmm4
movss  0x10(%rsi),%xmm0
mulss  %xmm4,%xmm0
movss  (%rsi),%xmm3
mulss  %xmm7,%xmm3
addss  %xmm0,%xmm3
movss  0x8(%rdx),%xmm2
movss  0x20(%rsi),%xmm0
mulss  %xmm2,%xmm0
addss  %xmm3,%xmm0
addss  0x30(%rsi),%xmm0
movaps %xmm4,%xmm3
shufps $0x0,%xmm4,%xmm3
movsd  0x4(%rsi),%xmm5
movsd  0x14(%rsi),%xmm6
mulps  %xmm3,%xmm6
movsd  0x24(%rsi),%xmm9
movsd  0x34(%rsi),%xmm8
movaps %xmm7,%xmm1
shufps $0x0,%xmm7,%xmm1
mulps  %xmm5,%xmm1
addps  %xmm6,%xmm1
movaps %xmm2,%xmm3
shufps $0x0,%xmm2,%xmm3
mulps  %xmm9,%xmm3
addps  %xmm1,%xmm3
mulss  0x1c(%rsi),%xmm4
mulss  0xc(%rsi),%xmm7
mulss  0x2c(%rsi),%xmm2
addss  %xmm4,%xmm7
addss  %xmm7,%xmm2
addss  0x3c(%rsi),%xmm2
addps  %xmm8,%xmm3
ucomiss 0xe69(%rip),%xmm2
jne    119b <mulmp+0x9b>
jnp    11cf <mulmp+0xcf>
xorps  %xmm1,%xmm1
cvtss2sd %xmm2,%xmm1
movsd  0xe5e(%rip),%xmm2
divsd  %xmm1,%xmm2
cvtss2sd %xmm0,%xmm0
mulsd  %xmm2,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rdi)
cvtps2pd %xmm3,%xmm0
unpcklpd %xmm2,%xmm2
mulpd  %xmm0,%xmm2
cvtpd2ps %xmm2,%xmm3
jmp    11d3 <mulmp+0xd3>
movss  %xmm0,(%rdi)
movss  %xmm3,0x4(%rdi)
shufps $0x55,%xmm3,%xmm3
movss  %xmm3,0x8(%rdi)
ret

LLVM IR (-O0):
define void @mulmp(float* %0, float* %1, float* %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca float*
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca double
store float* %0, float** %4
store float* %1, float** %5
store float* %2, float** %6
%12 = load float*, float** %5
%13 = getelementptr inbounds float, float* %12, i64 0
%14 = load float, float* %13
%15 = load float*, float** %6
%16 = getelementptr inbounds float, float* %15, i64 0
%17 = load float, float* %16
%18 = load float*, float** %5
%19 = getelementptr inbounds float, float* %18, i64 4
%20 = load float, float* %19
%21 = load float*, float** %6
%22 = getelementptr inbounds float, float* %21, i64 1
%23 = load float, float* %22
%24 = fmul float %20, %23
%25 = call float @llvm.fmuladd.f32(float %14, float %17, float %24)
%26 = load float*, float** %5
%27 = getelementptr inbounds float, float* %26, i64 8
%28 = load float, float* %27
%29 = load float*, float** %6
%30 = getelementptr inbounds float, float* %29, i64 2
%31 = load float, float* %30
%32 = call float @llvm.fmuladd.f32(float %28, float %31, float %25)
%33 = load float*, float** %5
%34 = getelementptr inbounds float, float* %33, i64 12
%35 = load float, float* %34
%36 = fadd float %32, %35
store float %36, float* %7
%37 = load float*, float** %5
%38 = getelementptr inbounds float, float* %37, i64 1
%39 = load float, float* %38
%40 = load float*, float** %6
%41 = getelementptr inbounds float, float* %40, i64 0
%42 = load float, float* %41
%43 = load float*, float** %5
%44 = getelementptr inbounds float, float* %43, i64 5
%45 = load float, float* %44
%46 = load float*, float** %6
%47 = getelementptr inbounds float, float* %46, i64 1
%48 = load float, float* %47
%49 = fmul float %45, %48
%50 = call float @llvm.fmuladd.f32(float %39, float %42, float %49)
%51 = load float*, float** %5
%52 = getelementptr inbounds float, float* %51, i64 9
%53 = load float, float* %52
%54 = load float*, float** %6
%55 = getelementptr inbounds float, float* %54, i64 2
%56 = load float, float* %55
%57 = call float @llvm.fmuladd.f32(float %53, float %56, float %50)
%58 = load float*, float** %5
%59 = getelementptr inbounds float, float* %58, i64 13
%60 = load float, float* %59
%61 = fadd float %57, %60
store float %61, float* %8
%62 = load float*, float** %5
%63 = getelementptr inbounds float, float* %62, i64 2
%64 = load float, float* %63
%65 = load float*, float** %6
%66 = getelementptr inbounds float, float* %65, i64 0
%67 = load float, float* %66
%68 = load float*, float** %5
%69 = getelementptr inbounds float, float* %68, i64 6
%70 = load float, float* %69
%71 = load float*, float** %6
%72 = getelementptr inbounds float, float* %71, i64 1
%73 = load float, float* %72
%74 = fmul float %70, %73
%75 = call float @llvm.fmuladd.f32(float %64, float %67, float %74)
%76 = load float*, float** %5
%77 = getelementptr inbounds float, float* %76, i64 10
%78 = load float, float* %77
%79 = load float*, float** %6
%80 = getelementptr inbounds float, float* %79, i64 2
%81 = load float, float* %80
%82 = call float @llvm.fmuladd.f32(float %78, float %81, float %75)
%83 = load float*, float** %5
%84 = getelementptr inbounds float, float* %83, i64 14
%85 = load float, float* %84
%86 = fadd float %82, %85
store float %86, float* %9
%87 = load float*, float** %5
%88 = getelementptr inbounds float, float* %87, i64 3
%89 = load float, float* %88
%90 = load float*, float** %6
%91 = getelementptr inbounds float, float* %90, i64 0
%92 = load float, float* %91
%93 = load float*, float** %5
%94 = getelementptr inbounds float, float* %93, i64 7
%95 = load float, float* %94
%96 = load float*, float** %6
%97 = getelementptr inbounds float, float* %96, i64 1
%98 = load float, float* %97
%99 = fmul float %95, %98
%100 = call float @llvm.fmuladd.f32(float %89, float %92, float %99)
%101 = load float*, float** %5
%102 = getelementptr inbounds float, float* %101, i64 11
%103 = load float, float* %102
%104 = load float*, float** %6
%105 = getelementptr inbounds float, float* %104, i64 2
%106 = load float, float* %105
%107 = call float @llvm.fmuladd.f32(float %103, float %106, float %100)
%108 = load float*, float** %5
%109 = getelementptr inbounds float, float* %108, i64 15
%110 = load float, float* %109
%111 = fadd float %107, %110
store float %111, float* %10
%112 = load float, float* %10
%113 = fcmp une float %112, 1.000000e+00
br i1 %113, label %114, label %139
114: ; preds = %3
%115 = load float, float* %10
%116 = fpext float %115 to double
%117 = fdiv double 1.000000e+00, %116
store double %117, double* %11
%118 = load float, float* %7
%119 = fpext float %118 to double
%120 = load double, double* %11
%121 = fmul double %119, %120
%122 = fptrunc double %121 to float
%123 = load float*, float** %4
%124 = getelementptr inbounds float, float* %123, i64 0
store float %122, float* %124
%125 = load float, float* %8
%126 = fpext float %125 to double
%127 = load double, double* %11
%128 = fmul double %126, %127
%129 = fptrunc double %128 to float
%130 = load float*, float** %4
%131 = getelementptr inbounds float, float* %130, i64 1
store float %129, float* %131
%132 = load float, float* %9
%133 = fpext float %132 to double
%134 = load double, double* %11
%135 = fmul double %133, %134
%136 = fptrunc double %135 to float
%137 = load float*, float** %4
%138 = getelementptr inbounds float, float* %137, i64 2
store float %136, float* %138
br label %149
139: ; preds = %3
%140 = load float, float* %7
%141 = load float*, float** %4
%142 = getelementptr inbounds float, float* %141, i64 0
store float %140, float* %142
%143 = load float, float* %8
%144 = load float*, float** %4
%145 = getelementptr inbounds float, float* %144, i64 1
store float %143, float* %145
%146 = load float, float* %9
%147 = load float*, float** %4
%148 = getelementptr inbounds float, float* %147, i64 2
store float %146, float* %148
br label %149
149: ; preds = %139, %114
ret void
}

LLVM IR (-O2):
define void @mulmp(float* nocapture writeonly %0, float* nocapture %1, float* nocapture %2) {
%4 = load float, float* %1
%5 = load float, float* %2
%6 = getelementptr inbounds float, float* %1, i64 4
%7 = load float, float* %6
%8 = getelementptr inbounds float, float* %2, i64 1
%9 = load float, float* %8
%10 = fmul float %7, %9
%11 = tail call float @llvm.fmuladd.f32(float %4, float %5, float %10)
%12 = getelementptr inbounds float, float* %1, i64 8
%13 = load float, float* %12
%14 = getelementptr inbounds float, float* %2, i64 2
%15 = load float, float* %14
%16 = tail call float @llvm.fmuladd.f32(float %13, float %15, float %11)
%17 = getelementptr inbounds float, float* %1, i64 12
%18 = load float, float* %17
%19 = fadd float %16, %18
%20 = getelementptr inbounds float, float* %1, i64 1
%21 = getelementptr inbounds float, float* %1, i64 5
%22 = getelementptr inbounds float, float* %1, i64 9
%23 = getelementptr inbounds float, float* %1, i64 13
%24 = bitcast float* %20 to <2 x float>*
%25 = load <2 x float>, <2 x float>* %24
%26 = bitcast float* %21 to <2 x float>*
%27 = load <2 x float>, <2 x float>* %26
%28 = insertelement <2 x float> poison, float %9, i64 0
%29 = shufflevector <2 x float> %28, <2 x float> poison, <2 x i32> zeroinitializer
%30 = fmul <2 x float> %29, %27
%31 = insertelement <2 x float> poison, float %5, i64 0
%32 = shufflevector <2 x float> %31, <2 x float> poison, <2 x i32> zeroinitializer
%33 = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %25, <2 x float> %32, <2 x float> %30)
%34 = bitcast float* %22 to <2 x float>*
%35 = load <2 x float>, <2 x float>* %34
%36 = insertelement <2 x float> poison, float %15, i64 0
%37 = shufflevector <2 x float> %36, <2 x float> poison, <2 x i32> zeroinitializer
%38 = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> %35, <2 x float> %37, <2 x float> %33)
%39 = bitcast float* %23 to <2 x float>*
%40 = load <2 x float>, <2 x float>* %39
%41 = fadd <2 x float> %40, %38
%42 = getelementptr inbounds float, float* %1, i64 3
%43 = load float, float* %42
%44 = getelementptr inbounds float, float* %1, i64 7
%45 = load float, float* %44
%46 = fmul float %9, %45
%47 = tail call float @llvm.fmuladd.f32(float %43, float %5, float %46)
%48 = getelementptr inbounds float, float* %1, i64 11
%49 = load float, float* %48
%50 = tail call float @llvm.fmuladd.f32(float %49, float %15, float %47)
%51 = getelementptr inbounds float, float* %1, i64 15
%52 = load float, float* %51
%53 = fadd float %52, %50
%54 = fcmp une float %53, 1.000000e+00
br i1 %54, label %55, label %66
55: ; preds = %3
%56 = fpext float %53 to double
%57 = fdiv double 1.000000e+00, %56
%58 = fpext float %19 to double
%59 = fmul double %57, %58
%60 = fptrunc double %59 to float
store float %60, float* %0
%61 = fpext <2 x float> %41 to <2 x double>
%62 = insertelement <2 x double> poison, double %57, i64 0
%63 = shufflevector <2 x double> %62, <2 x double> poison, <2 x i32> zeroinitializer
%64 = fmul <2 x double> %63, %61
%65 = fptrunc <2 x double> %64 to <2 x float>
br label %67
66: ; preds = %3
store float %19, float* %0
br label %67
67: ; preds = %66, %55
%68 = phi <2 x float> [ %65, %55 ], [ %41, %66 ]
%69 = getelementptr inbounds float, float* %0, i64 1
%70 = extractelement <2 x float> %68, i64 0
store float %70, float* %69
%71 = getelementptr inbounds float, float* %0, i64 2
%72 = extractelement <2 x float> %68, i64 1
store float %72, float* %71
ret void
}