void mat4_multiply(float *dst, float *b) {
  float a00 = dst[0], a01 = dst[1], a02 = dst[2], a03 = dst[3];
  float a10 = dst[4], a11 = dst[5], a12 = dst[6], a13 = dst[7];
  float a20 = dst[8], a21 = dst[9], a22 = dst[10], a23 = dst[11];
  float a30 = dst[12], a31 = dst[13], a32 = dst[14], a33 = dst[15];
  float b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
  dst[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  dst[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  dst[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  dst[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[4];
  b1 = b[5];
  b2 = b[6];
  b3 = b[7];
  dst[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  dst[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  dst[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  dst[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[8];
  b1 = b[9];
  b2 = b[10];
  b3 = b[11];
  dst[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  dst[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  dst[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  dst[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[12];
  b1 = b[13];
  b2 = b[14];
  b3 = b[15];
  dst[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  dst[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  dst[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  dst[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
}


x86 assembly (clang, -O0):
<mat4_multiply>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x14(%rbp)
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movss  0x10(%rax),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x8(%rbp),%rax
movss  0x14(%rax),%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
movss  0x18(%rax),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x8(%rbp),%rax
movss  0x1c(%rax),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x8(%rbp),%rax
movss  0x20(%rax),%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x8(%rbp),%rax
movss  0x24(%rax),%xmm0
movss  %xmm0,-0x38(%rbp)
mov    -0x8(%rbp),%rax
movss  0x28(%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x8(%rbp),%rax
movss  0x2c(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x8(%rbp),%rax
movss  0x30(%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x8(%rbp),%rax
movss  0x34(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
mov    -0x8(%rbp),%rax
movss  0x38(%rax),%xmm0
movss  %xmm0,-0x4c(%rbp)
mov    -0x8(%rbp),%rax
movss  0x3c(%rax),%xmm0
movss  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x10(%rbp),%rax
movss  0xc(%rax),%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x54(%rbp),%xmm0
movss  -0x14(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x24(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x34(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x18(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x28(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x38(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x2c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x3c(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x4c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x30(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x40(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x50(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
mov    -0x10(%rbp),%rax
movss  0x10(%rax),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x10(%rbp),%rax
movss  0x14(%rax),%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x18(%rax),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x1c(%rax),%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x54(%rbp),%xmm0
movss  -0x14(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x24(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x34(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x10(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x18(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x28(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x38(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x14(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x2c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x3c(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x4c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x18(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x30(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x40(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x50(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x1c(%rax)
mov    -0x10(%rbp),%rax
movss  0x20(%rax),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x10(%rbp),%rax
movss  0x24(%rax),%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x28(%rax),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x2c(%rax),%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x54(%rbp),%xmm0
movss  -0x14(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x24(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x34(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x20(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x18(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x28(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x38(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x24(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x2c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x3c(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x4c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x28(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x30(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x40(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x50(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x2c(%rax)
mov    -0x10(%rbp),%rax
movss  0x30(%rax),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x10(%rbp),%rax
movss  0x34(%rax),%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x38(%rax),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x3c(%rax),%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x54(%rbp),%xmm0
movss  -0x14(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x24(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x34(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x30(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x18(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x28(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x38(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x34(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x2c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x3c(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x4c(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x38(%rax)
movss  -0x54(%rbp),%xmm0
movss  -0x20(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  -0x30(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x5c(%rbp),%xmm1
movss  -0x40(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x60(%rbp),%xmm0
movss  -0x50(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x3c(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<mat4_multiply>:
movups (%rdi),%xmm2
movups 0x10(%rdi),%xmm3
movups 0x20(%rdi),%xmm1
movups 0x30(%rdi),%xmm0
movss  (%rsi),%xmm4
movss  0x4(%rsi),%xmm5
movss  0x8(%rsi),%xmm6
movss  0xc(%rsi),%xmm7
shufps $0x0,%xmm5,%xmm5
mulps  %xmm3,%xmm5
shufps $0x0,%xmm4,%xmm4
mulps  %xmm2,%xmm4
addps  %xmm5,%xmm4
shufps $0x0,%xmm6,%xmm6
mulps  %xmm1,%xmm6
addps  %xmm4,%xmm6
shufps $0x0,%xmm7,%xmm7
mulps  %xmm0,%xmm7
addps  %xmm6,%xmm7
movups %xmm7,(%rdi)
movss  0x10(%rsi),%xmm4
movss  0x14(%rsi),%xmm5
movss  0x18(%rsi),%xmm6
movss  0x1c(%rsi),%xmm7
shufps $0x0,%xmm5,%xmm5
mulps  %xmm3,%xmm5
shufps $0x0,%xmm4,%xmm4
mulps  %xmm2,%xmm4
addps  %xmm5,%xmm4
shufps $0x0,%xmm6,%xmm6
mulps  %xmm1,%xmm6
addps  %xmm4,%xmm6
shufps $0x0,%xmm7,%xmm7
mulps  %xmm0,%xmm7
addps  %xmm6,%xmm7
movups %xmm7,0x10(%rdi)
movss  0x20(%rsi),%xmm4
movss  0x24(%rsi),%xmm5
movss  0x28(%rsi),%xmm6
movss  0x2c(%rsi),%xmm7
shufps $0x0,%xmm5,%xmm5
mulps  %xmm3,%xmm5
shufps $0x0,%xmm4,%xmm4
mulps  %xmm2,%xmm4
addps  %xmm5,%xmm4
shufps $0x0,%xmm6,%xmm6
mulps  %xmm1,%xmm6
addps  %xmm4,%xmm6
shufps $0x0,%xmm7,%xmm7
mulps  %xmm0,%xmm7
addps  %xmm6,%xmm7
movups %xmm7,0x20(%rdi)
movss  0x30(%rsi),%xmm4
movss  0x34(%rsi),%xmm5
movss  0x38(%rsi),%xmm6
movss  0x3c(%rsi),%xmm7
shufps $0x0,%xmm5,%xmm5
mulps  %xmm3,%xmm5
shufps $0x0,%xmm4,%xmm4
mulps  %xmm2,%xmm4
addps  %xmm5,%xmm4
shufps $0x0,%xmm6,%xmm6
mulps  %xmm1,%xmm6
addps  %xmm4,%xmm6
shufps $0x0,%xmm7,%xmm7
mulps  %xmm0,%xmm7
addps  %xmm6,%xmm7
movups %xmm7,0x30(%rdi)
ret

LLVM IR (-O0):
define void @mat4_multiply(float* %0, float* %1) {
%3 = alloca float*
%4 = alloca float*
%5 = alloca float
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca float
%12 = alloca float
%13 = alloca float
%14 = alloca float
%15 = alloca float
%16 = alloca float
%17 = alloca float
%18 = alloca float
%19 = alloca float
%20 = alloca float
%21 = alloca float
%22 = alloca float
%23 = alloca float
%24 = alloca float
store float* %0, float** %3
store float* %1, float** %4
%25 = load float*, float** %3
%26 = getelementptr inbounds float, float* %25, i64 0
%27 = load float, float* %26
store float %27, float* %5
%28 = load float*, float** %3
%29 = getelementptr inbounds float, float* %28, i64 1
%30 = load float, float* %29
store float %30, float* %6
%31 = load float*, float** %3
%32 = getelementptr inbounds float, float* %31, i64 2
%33 = load float, float* %32
store float %33, float* %7
%34 = load float*, float** %3
%35 = getelementptr inbounds float, float* %34, i64 3
%36 = load float, float* %35
store float %36, float* %8
%37 = load float*, float** %3
%38 = getelementptr inbounds float, float* %37, i64 4
%39 = load float, float* %38
store float %39, float* %9
%40 = load float*, float** %3
%41 = getelementptr inbounds float, float* %40, i64 5
%42 = load float, float* %41
store float %42, float* %10
%43 = load float*, float** %3
%44 = getelementptr inbounds float, float* %43, i64 6
%45 = load float, float* %44
store float %45, float* %11
%46 = load float*, float** %3
%47 = getelementptr inbounds float, float* %46, i64 7
%48 = load float, float* %47
store float %48, float* %12
%49 = load float*, float** %3
%50 = getelementptr inbounds float, float* %49, i64 8
%51 = load float, float* %50
store float %51, float* %13
%52 = load float*, float** %3
%53 = getelementptr inbounds float, float* %52, i64 9
%54 = load float, float* %53
store float %54, float* %14
%55 = load float*, float** %3
%56 = getelementptr inbounds float, float* %55, i64 10
%57 = load float, float* %56
store float %57, float* %15
%58 = load float*, float** %3
%59 = getelementptr inbounds float, float* %58, i64 11
%60 = load float, float* %59
store float %60, float* %16
%61 = load float*, float** %3
%62 = getelementptr inbounds float, float* %61, i64 12
%63 = load float, float* %62
store float %63, float* %17
%64 = load float*, float** %3
%65 = getelementptr inbounds float, float* %64, i64 13
%66 = load float, float* %65
store float %66, float* %18
%67 = load float*, float** %3
%68 = getelementptr inbounds float, float* %67, i64 14
%69 = load float, float* %68
store float %69, float* %19
%70 = load float*, float** %3
%71 = getelementptr inbounds float, float* %70, i64 15
%72 = load float, float* %71
store float %72, float* %20
%73 = load float*, float** %4
%74 = getelementptr inbounds float, float* %73, i64 0
%75 = load float, float* %74
store float %75, float* %21
%76 = load float*, float** %4
%77 = getelementptr inbounds float, float* %76, i64 1
%78 = load float, float* %77
store float %78, float* %22
%79 = load float*, float** %4
%80 = getelementptr inbounds float, float* %79, i64 2
%81 = load float, float* %80
store float %81, float* %23
%82 = load float*, float** %4
%83 = getelementptr inbounds float, float* %82, i64 3
%84 = load float, float* %83
store float %84, float* %24
%85 = load float, float* %21
%86 = load float, float* %5
%87 = load float, float* %22
%88 = load float, float* %9
%89 = fmul float %87, %88
%90 = call float @llvm.fmuladd.f32(float %85, float %86, float %89)
%91 = load float, float* %23
%92 = load float, float* %13
%93 = call float @llvm.fmuladd.f32(float %91, float %92, float %90)
%94 = load float, float* %24
%95 = load float, float* %17
%96 = call float @llvm.fmuladd.f32(float %94, float %95, float %93)
%97 = load float*, float** %3
%98 = getelementptr inbounds float, float* %97, i64 0
store float %96, float* %98
%99 = load float, float* %21
%100 = load float, float* %6
%101 = load float, float* %22
%102 = load float, float* %10
%103 = fmul float %101, %102
%104 = call float @llvm.fmuladd.f32(float %99, float %100, float %103)
%105 = load float, float* %23
%106 = load float, float* %14
%107 = call float @llvm.fmuladd.f32(float %105, float %106, float %104)
%108 = load float, float* %24
%109 = load float, float* %18
%110 = call float @llvm.fmuladd.f32(float %108, float %109, float %107)
%111 = load float*, float** %3
%112 = getelementptr inbounds float, float* %111, i64 1
store float %110, float* %112
%113 = load float, float* %21
%114 = load float, float* %7
%115 = load float, float* %22
%116 = load float, float* %11
%117 = fmul float %115, %116
%118 = call float @llvm.fmuladd.f32(float %113, float %114, float %117)
%119 = load float, float* %23
%120 = load float, float* %15
%121 = call float @llvm.fmuladd.f32(float %119, float %120, float %118)
%122 = load float, float* %24
%123 = load float, float* %19
%124 = call float @llvm.fmuladd.f32(float %122, float %123, float %121)
%125 = load float*, float** %3
%126 = getelementptr inbounds float, float* %125, i64 2
store float %124, float* %126
%127 = load float, float* %21
%128 = load float, float* %8
%129 = load float, float* %22
%130 = load float, float* %12
%131 = fmul float %129, %130
%132 = call float @llvm.fmuladd.f32(float %127, float %128, float %131)
%133 = load float, float* %23
%134 = load float, float* %16
%135 = call float @llvm.fmuladd.f32(float %133, float %134, float %132)
%136 = load float, float* %24
%137 = load float, float* %20
%138 = call float @llvm.fmuladd.f32(float %136, float %137, float %135)
%139 = load float*, float** %3
%140 = getelementptr inbounds float, float* %139, i64 3
store float %138, float* %140
%141 = load float*, float** %4
%142 = getelementptr inbounds float, float* %141, i64 4
%143 = load float, float* %142
store float %143, float* %21
%144 = load float*, float** %4
%145 = getelementptr inbounds float, float* %144, i64 5
%146 = load float, float* %145
store float %146, float* %22
%147 = load float*, float** %4
%148 = getelementptr inbounds float, float* %147, i64 6
%149 = load float, float* %148
store float %149, float* %23
%150 = load float*, float** %4
%151 = getelementptr inbounds float, float* %150, i64 7
%152 = load float, float* %151
store float %152, float* %24
%153 = load float, float* %21
%154 = load float, float* %5
%155 = load float, float* %22
%156 = load float, float* %9
%157 = fmul float %155, %156
%158 = call float @llvm.fmuladd.f32(float %153, float %154, float %157)
%159 = load float, float* %23
%160 = load float, float* %13
%161 = call float @llvm.fmuladd.f32(float %159, float %160, float %158)
%162 = load float, float* %24
%163 = load float, float* %17
%164 = call float @llvm.fmuladd.f32(float %162, float %163, float %161)
%165 = load float*, float** %3
%166 = getelementptr inbounds float, float* %165, i64 4
store float %164, float* %166
%167 = load float, float* %21
%168 = load float, float* %6
%169 = load float, float* %22
%170 = load float, float* %10
%171 = fmul float %169, %170
%172 = call float @llvm.fmuladd.f32(float %167, float %168, float %171)
%173 = load float, float* %23
%174 = load float, float* %14
%175 = call float @llvm.fmuladd.f32(float %173, float %174, float %172)
%176 = load float, float* %24
%177 = load float, float* %18
%178 = call float @llvm.fmuladd.f32(float %176, float %177, float %175)
%179 = load float*, float** %3
%180 = getelementptr inbounds float, float* %179, i64 5
store float %178, float* %180
%181 = load float, float* %21
%182 = load float, float* %7
%183 = load float, float* %22
%184 = load float, float* %11
%185 = fmul float %183, %184
%186 = call float @llvm.fmuladd.f32(float %181, float %182, float %185)
%187 = load float, float* %23
%188 = load float, float* %15
%189 = call float @llvm.fmuladd.f32(float %187, float %188, float %186)
%190 = load float, float* %24
%191 = load float, float* %19
%192 = call float @llvm.fmuladd.f32(float %190, float %191, float %189)
%193 = load float*, float** %3
%194 = getelementptr inbounds float, float* %193, i64 6
store float %192, float* %194
%195 = load float, float* %21
%196 = load float, float* %8
%197 = load float, float* %22
%198 = load float, float* %12
%199 = fmul float %197, %198
%200 = call float @llvm.fmuladd.f32(float %195, float %196, float %199)
%201 = load float, float* %23
%202 = load float, float* %16
%203 = call float @llvm.fmuladd.f32(float %201, float %202, float %200)
%204 = load float, float* %24
%205 = load float, float* %20
%206 = call float @llvm.fmuladd.f32(float %204, float %205, float %203)
%207 = load float*, float** %3
%208 = getelementptr inbounds float, float* %207, i64 7
store float %206, float* %208
%209 = load float*, float** %4
%210 = getelementptr inbounds float, float* %209, i64 8
%211 = load float, float* %210
store float %211, float* %21
%212 = load float*, float** %4
%213 = getelementptr inbounds float, float* %212, i64 9
%214 = load float, float* %213
store float %214, float* %22
%215 = load float*, float** %4
%216 = getelementptr inbounds float, float* %215, i64 10
%217 = load float, float* %216
store float %217, float* %23
%218 = load float*, float** %4
%219 = getelementptr inbounds float, float* %218, i64 11
%220 = load float, float* %219
store float %220, float* %24
%221 = load float, float* %21
%222 = load float, float* %5
%223 = load float, float* %22
%224 = load float, float* %9
%225 = fmul float %223, %224
%226 = call float @llvm.fmuladd.f32(float %221, float %222, float %225)
%227 = load float, float* %23
%228 = load float, float* %13
%229 = call float @llvm.fmuladd.f32(float %227, float %228, float %226)
%230 = load float, float* %24
%231 = load float, float* %17
%232 = call float @llvm.fmuladd.f32(float %230, float %231, float %229)
%233 = load float*, float** %3
%234 = getelementptr inbounds float, float* %233, i64 8
store float %232, float* %234
%235 = load float, float* %21
%236 = load float, float* %6
%237 = load float, float* %22
%238 = load float, float* %10
%239 = fmul float %237, %238
%240 = call float @llvm.fmuladd.f32(float %235, float %236, float %239)
%241 = load float, float* %23
%242 = load float, float* %14
%243 = call float @llvm.fmuladd.f32(float %241, float %242, float %240)
%244 = load float, float* %24
%245 = load float, float* %18
%246 = call float @llvm.fmuladd.f32(float %244, float %245, float %243)
%247 = load float*, float** %3
%248 = getelementptr inbounds float, float* %247, i64 9
store float %246, float* %248
%249 = load float, float* %21
%250 = load float, float* %7
%251 = load float, float* %22
%252 = load float, float* %11
%253 = fmul float %251, %252
%254 = call float @llvm.fmuladd.f32(float %249, float %250, float %253)
%255 = load float, float* %23
%256 = load float, float* %15
%257 = call float @llvm.fmuladd.f32(float %255, float %256, float %254)
%258 = load float, float* %24
%259 = load float, float* %19
%260 = call float @llvm.fmuladd.f32(float %258, float %259, float %257)
%261 = load float*, float** %3
%262 = getelementptr inbounds float, float* %261, i64 10
store float %260, float* %262
%263 = load float, float* %21
%264 = load float, float* %8
%265 = load float, float* %22
%266 = load float, float* %12
%267 = fmul float %265, %266
%268 = call float @llvm.fmuladd.f32(float %263, float %264, float %267)
%269 = load float, float* %23
%270 = load float, float* %16
%271 = call float @llvm.fmuladd.f32(float %269, float %270, float %268)
%272 = load float, float* %24
%273 = load float, float* %20
%274 = call float @llvm.fmuladd.f32(float %272, float %273, float %271)
%275 = load float*, float** %3
%276 = getelementptr inbounds float, float* %275, i64 11
store float %274, float* %276
%277 = load float*, float** %4
%278 = getelementptr inbounds float, float* %277, i64 12
%279 = load float, float* %278
store float %279, float* %21
%280 = load float*, float** %4
%281 = getelementptr inbounds float, float* %280, i64 13
%282 = load float, float* %281
store float %282, float* %22
%283 = load float*, float** %4
%284 = getelementptr inbounds float, float* %283, i64 14
%285 = load float, float* %284
store float %285, float* %23
%286 = load float*, float** %4
%287 = getelementptr inbounds float, float* %286, i64 15
%288 = load float, float* %287
store float %288, float* %24
%289 = load float, float* %21
%290 = load float, float* %5
%291 = load float, float* %22
%292 = load float, float* %9
%293 = fmul float %291, %292
%294 = call float @llvm.fmuladd.f32(float %289, float %290, float %293)
%295 = load float, float* %23
%296 = load float, float* %13
%297 = call float @llvm.fmuladd.f32(float %295, float %296, float %294)
%298 = load float, float* %24
%299 = load float, float* %17
%300 = call float @llvm.fmuladd.f32(float %298, float %299, float %297)
%301 = load float*, float** %3
%302 = getelementptr inbounds float, float* %301, i64 12
store float %300, float* %302
%303 = load float, float* %21
%304 = load float, float* %6
%305 = load float, float* %22
%306 = load float, float* %10
%307 = fmul float %305, %306
%308 = call float @llvm.fmuladd.f32(float %303, float %304, float %307)
%309 = load float, float* %23
%310 = load float, float* %14
%311 = call float @llvm.fmuladd.f32(float %309, float %310, float %308)
%312 = load float, float* %24
%313 = load float, float* %18
%314 = call float @llvm.fmuladd.f32(float %312, float %313, float %311)
%315 = load float*, float** %3
%316 = getelementptr inbounds float, float* %315, i64 13
store float %314, float* %316
%317 = load float, float* %21
%318 = load float, float* %7
%319 = load float, float* %22
%320 = load float, float* %11
%321 = fmul float %319, %320
%322 = call float @llvm.fmuladd.f32(float %317, float %318, float %321)
%323 = load float, float* %23
%324 = load float, float* %15
%325 = call float @llvm.fmuladd.f32(float %323, float %324, float %322)
%326 = load float, float* %24
%327 = load float, float* %19
%328 = call float @llvm.fmuladd.f32(float %326, float %327, float %325)
%329 = load float*, float** %3
%330 = getelementptr inbounds float, float* %329, i64 14
store float %328, float* %330
%331 = load float, float* %21
%332 = load float, float* %8
%333 = load float, float* %22
%334 = load float, float* %12
%335 = fmul float %333, %334
%336 = call float @llvm.fmuladd.f32(float %331, float %332, float %335)
%337 = load float, float* %23
%338 = load float, float* %16
%339 = call float @llvm.fmuladd.f32(float %337, float %338, float %336)
%340 = load float, float* %24
%341 = load float, float* %20
%342 = call float @llvm.fmuladd.f32(float %340, float %341, float %339)
%343 = load float*, float** %3
%344 = getelementptr inbounds float, float* %343, i64 15
store float %342, float* %344
ret void
}

LLVM IR (-O2):
define void @mat4_multiply(float* nocapture %0, float* nocapture %1) {
%3 = bitcast float* %0 to <4 x float>*
%4 = load <4 x float>, <4 x float>* %3
%5 = getelementptr inbounds float, float* %0, i64 4
%6 = bitcast float* %5 to <4 x float>*
%7 = load <4 x float>, <4 x float>* %6
%8 = getelementptr inbounds float, float* %0, i64 8
%9 = bitcast float* %8 to <4 x float>*
%10 = load <4 x float>, <4 x float>* %9
%11 = getelementptr inbounds float, float* %0, i64 12
%12 = bitcast float* %11 to <4 x float>*
%13 = load <4 x float>, <4 x float>* %12
%14 = load float, float* %1
%15 = getelementptr inbounds float, float* %1, i64 1
%16 = load float, float* %15
%17 = getelementptr inbounds float, float* %1, i64 2
%18 = load float, float* %17
%19 = getelementptr inbounds float, float* %1, i64 3
%20 = load float, float* %19
%21 = insertelement <4 x float> poison, float %16, i64 0
%22 = shufflevector <4 x float> %21, <4 x float> poison, <4 x i32> zeroinitializer
%23 = fmul <4 x float> %7, %22
%24 = insertelement <4 x float> poison, float %14, i64 0
%25 = shufflevector <4 x float> %24, <4 x float> poison, <4 x i32> zeroinitializer
%26 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %25, <4 x float> %4, <4 x float> %23)
%27 = insertelement <4 x float> poison, float %18, i64 0
%28 = shufflevector <4 x float> %27, <4 x float> poison, <4 x i32> zeroinitializer
%29 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %28, <4 x float> %10, <4 x float> %26)
%30 = insertelement <4 x float> poison, float %20, i64 0
%31 = shufflevector <4 x float> %30, <4 x float> poison, <4 x i32> zeroinitializer
%32 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %31, <4 x float> %13, <4 x float> %29)
%33 = bitcast float* %0 to <4 x float>*
store <4 x float> %32, <4 x float>* %33
%34 = getelementptr inbounds float, float* %1, i64 4
%35 = load float, float* %34
%36 = getelementptr inbounds float, float* %1, i64 5
%37 = load float, float* %36
%38 = getelementptr inbounds float, float* %1, i64 6
%39 = load float, float* %38
%40 = getelementptr inbounds float, float* %1, i64 7
%41 = load float, float* %40
%42 = insertelement <4 x float> poison, float %37, i64 0
%43 = shufflevector <4 x float> %42, <4 x float> poison, <4 x i32> zeroinitializer
%44 = fmul <4 x float> %7, %43
%45 = insertelement <4 x float> poison, float %35, i64 0
%46 = shufflevector <4 x float> %45, <4 x float> poison, <4 x i32> zeroinitializer
%47 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %46, <4 x float> %4, <4 x float> %44)
%48 = insertelement <4 x float> poison, float %39, i64 0
%49 = shufflevector <4 x float> %48, <4 x float> poison, <4 x i32> zeroinitializer
%50 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %49, <4 x float> %10, <4 x float> %47)
%51 = insertelement <4 x float> poison, float %41, i64 0
%52 = shufflevector <4 x float> %51, <4 x float> poison, <4 x i32> zeroinitializer
%53 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %52, <4 x float> %13, <4 x float> %50)
%54 = bitcast float* %5 to <4 x float>*
store <4 x float> %53, <4 x float>* %54
%55 = getelementptr inbounds float, float* %1, i64 8
%56 = load float, float* %55
%57 = getelementptr inbounds float, float* %1, i64 9
%58 = load float, float* %57
%59 = getelementptr inbounds float, float* %1, i64 10
%60 = load float, float* %59
%61 = getelementptr inbounds float, float* %1, i64 11
%62 = load float, float* %61
%63 = insertelement <4 x float> poison, float %58, i64 0
%64 = shufflevector <4 x float> %63, <4 x float> poison, <4 x i32> zeroinitializer
%65 = fmul <4 x float> %7, %64
%66 = insertelement <4 x float> poison, float %56, i64 0
%67 = shufflevector <4 x float> %66, <4 x float> poison, <4 x i32> zeroinitializer
%68 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %67, <4 x float> %4, <4 x float> %65)
%69 = insertelement <4 x float> poison, float %60, i64 0
%70 = shufflevector <4 x float> %69, <4 x float> poison, <4 x i32> zeroinitializer
%71 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %70, <4 x float> %10, <4 x float> %68)
%72 = insertelement <4 x float> poison, float %62, i64 0
%73 = shufflevector <4 x float> %72, <4 x float> poison, <4 x i32> zeroinitializer
%74 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %13, <4 x float> %71)
%75 = bitcast float* %8 to <4 x float>*
store <4 x float> %74, <4 x float>* %75
%76 = getelementptr inbounds float, float* %1, i64 12
%77 = load float, float* %76
%78 = getelementptr inbounds float, float* %1, i64 13
%79 = load float, float* %78
%80 = getelementptr inbounds float, float* %1, i64 14
%81 = load float, float* %80
%82 = getelementptr inbounds float, float* %1, i64 15
%83 = load float, float* %82
%84 = insertelement <4 x float> poison, float %79, i64 0
%85 = shufflevector <4 x float> %84, <4 x float> poison, <4 x i32> zeroinitializer
%86 = fmul <4 x float> %7, %85
%87 = insertelement <4 x float> poison, float %77, i64 0
%88 = shufflevector <4 x float> %87, <4 x float> poison, <4 x i32> zeroinitializer
%89 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %88, <4 x float> %4, <4 x float> %86)
%90 = insertelement <4 x float> poison, float %81, i64 0
%91 = shufflevector <4 x float> %90, <4 x float> poison, <4 x i32> zeroinitializer
%92 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %91, <4 x float> %10, <4 x float> %89)
%93 = insertelement <4 x float> poison, float %83, i64 0
%94 = shufflevector <4 x float> %93, <4 x float> poison, <4 x i32> zeroinitializer
%95 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %94, <4 x float> %13, <4 x float> %92)
%96 = bitcast float* %11 to <4 x float>*
store <4 x float> %95, <4 x float>* %96
ret void
}