void kernel_sgemm_nt_2x2_lib4(int kmax, float *A, float *B, float *D, float *C,
                              int alg) {
  if (kmax <= 0)
    return;
  const int lda = 4;
  const int ldc = 4;
  int k;
  float a_0, a_1, b_0, b_1, c_00 = 0, c_01 = 0, c_10 = 0, c_11 = 0;
  for (k = 0; k < kmax - 3; k += 4) {
    a_0 = A[0 + lda * 0];
    a_1 = A[1 + lda * 0];
    b_0 = B[0 + lda * 0];
    b_1 = B[1 + lda * 0];
    c_00 += a_0 * b_0;
    c_10 += a_1 * b_0;
    c_01 += a_0 * b_1;
    c_11 += a_1 * b_1;
    a_0 = A[0 + lda * 1];
    a_1 = A[1 + lda * 1];
    b_0 = B[0 + lda * 1];
    b_1 = B[1 + lda * 1];
    c_00 += a_0 * b_0;
    c_10 += a_1 * b_0;
    c_01 += a_0 * b_1;
    c_11 += a_1 * b_1;
    a_0 = A[0 + lda * 2];
    a_1 = A[1 + lda * 2];
    b_0 = B[0 + lda * 2];
    b_1 = B[1 + lda * 2];
    c_00 += a_0 * b_0;
    c_10 += a_1 * b_0;
    c_01 += a_0 * b_1;
    c_11 += a_1 * b_1;
    a_0 = A[0 + lda * 3];
    a_1 = A[1 + lda * 3];
    b_0 = B[0 + lda * 3];
    b_1 = B[1 + lda * 3];
    c_00 += a_0 * b_0;
    c_10 += a_1 * b_0;
    c_01 += a_0 * b_1;
    c_11 += a_1 * b_1;
    A += 16;
    B += 16;
  }
  for (; k < kmax; k++) {
    a_0 = A[0 + lda * 0];
    a_1 = A[1 + lda * 0];
    b_0 = B[0 + lda * 0];
    b_1 = B[1 + lda * 0];
    c_00 += a_0 * b_0;
    c_10 += a_1 * b_0;
    c_01 += a_0 * b_1;
    c_11 += a_1 * b_1;
    A += 4;
    B += 4;
  }
  float d_00, d_01, d_10, d_11;
  if (alg == 0) {
    C[0 + ldc * 0] = c_00;
    C[1 + ldc * 0] = c_10;
    C[0 + ldc * 1] = c_01;
    C[1 + ldc * 1] = c_11;
  } else {
    d_00 = D[0 + ldc * 0];
    d_10 = D[1 + ldc * 0];
    d_01 = D[0 + ldc * 1];
    d_11 = D[1 + ldc * 1];
    if (alg == 1) {
      d_00 += c_00;
      d_10 += c_10;
      d_01 += c_01;
      d_11 += c_11;
    } else {
      d_00 -= c_00;
      d_10 -= c_10;
      d_01 -= c_01;
      d_11 -= c_11;
    }
    C[0 + ldc * 0] = d_00;
    C[1 + ldc * 0] = d_10;
    C[0 + ldc * 1] = d_01;
    C[1 + ldc * 1] = d_11;
  }
}


x86 assembly (clang, -O0):
<kernel_sgemm_nt_2x2_lib4>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9d,-0x2c(%rbp)
cmpl   $0x0,-0x4(%rbp)
jg     112a <kernel_sgemm_nt_2x2_lib4+0x2a>
jmp    165c <kernel_sgemm_nt_2x2_lib4+0x55c>
movl   $0x4,-0x30(%rbp)
movl   $0x4,-0x34(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4c(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x54(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x58(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x3,%ecx
cmp    %ecx,%eax
jge    1434 <kernel_sgemm_nt_2x2_lib4+0x334>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x54(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x50(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x10(%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x14(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movss  0x10(%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x18(%rbp),%rax
movss  0x14(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x54(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x50(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x20(%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x24(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movss  0x20(%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x18(%rbp),%rax
movss  0x24(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x54(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x50(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movss  0x30(%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x34(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movss  0x30(%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x18(%rbp),%rax
movss  0x34(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x54(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x50(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
add    $0x40,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x40,%rax
mov    %rax,-0x18(%rbp)
mov    -0x38(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x38(%rbp)
jmp    115f <kernel_sgemm_nt_2x2_lib4+0x5f>
jmp    1439 <kernel_sgemm_nt_2x2_lib4+0x339>
mov    -0x38(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1511 <kernel_sgemm_nt_2x2_lib4+0x411>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x44(%rbp)
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x4c(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm2
movss  -0x54(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x3c(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x50(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x48(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x18(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1439 <kernel_sgemm_nt_2x2_lib4+0x339>
cmpl   $0x0,-0x2c(%rbp)
jne    1557 <kernel_sgemm_nt_2x2_lib4+0x457>
movss  -0x4c(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x54(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x50(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x10(%rax)
movss  -0x58(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x14(%rax)
jmp    165c <kernel_sgemm_nt_2x2_lib4+0x55c>
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x5c(%rbp)
mov    -0x20(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  %xmm0,-0x64(%rbp)
mov    -0x20(%rbp),%rax
movss  0x10(%rax),%xmm0
movss  %xmm0,-0x60(%rbp)
mov    -0x20(%rbp),%rax
movss  0x14(%rax),%xmm0
movss  %xmm0,-0x68(%rbp)
cmpl   $0x1,-0x2c(%rbp)
jne    15d9 <kernel_sgemm_nt_2x2_lib4+0x4d9>
movss  -0x4c(%rbp),%xmm0
addss  -0x5c(%rbp),%xmm0
movss  %xmm0,-0x5c(%rbp)
movss  -0x54(%rbp),%xmm0
addss  -0x64(%rbp),%xmm0
movss  %xmm0,-0x64(%rbp)
movss  -0x50(%rbp),%xmm0
addss  -0x60(%rbp),%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x58(%rbp),%xmm0
addss  -0x68(%rbp),%xmm0
movss  %xmm0,-0x68(%rbp)
jmp    1625 <kernel_sgemm_nt_2x2_lib4+0x525>
movss  -0x4c(%rbp),%xmm1
movss  -0x5c(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x5c(%rbp)
movss  -0x54(%rbp),%xmm1
movss  -0x64(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x64(%rbp)
movss  -0x50(%rbp),%xmm1
movss  -0x60(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x58(%rbp),%xmm1
movss  -0x68(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x68(%rbp)
movss  -0x5c(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x64(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x60(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x10(%rax)
movss  -0x68(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,0x14(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<kernel_sgemm_nt_2x2_lib4>:
test   %edi,%edi
jle    1226 <kernel_sgemm_nt_2x2_lib4+0x126>
cmp    $0x4,%edi
jb     119a <kernel_sgemm_nt_2x2_lib4+0x9a>
lea    -0x3(%rdi),%r10d
xorps  %xmm2,%xmm2
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movsd  (%rsi),%xmm4
movsd  0x10(%rsi),%xmm5
movsd  0x20(%rsi),%xmm6
movsd  0x30(%rsi),%xmm8
movlhps %xmm4,%xmm4
movsd  (%rdx),%xmm7
movsd  0x10(%rdx),%xmm3
movsd  0x20(%rdx),%xmm1
movsd  0x30(%rdx),%xmm0
unpcklps %xmm7,%xmm7
mulps  %xmm4,%xmm7
addps  %xmm2,%xmm7
movlhps %xmm5,%xmm5
unpcklps %xmm3,%xmm3
mulps  %xmm5,%xmm3
addps  %xmm7,%xmm3
movlhps %xmm6,%xmm6
unpcklps %xmm1,%xmm1
mulps  %xmm6,%xmm1
addps  %xmm3,%xmm1
movlhps %xmm8,%xmm8
unpcklps %xmm0,%xmm0
mulps  %xmm8,%xmm0
movaps %xmm0,%xmm2
addps  %xmm1,%xmm2
add    $0x40,%rsi
add    $0x40,%rdx
add    $0x4,%eax
cmp    %r10d,%eax
jl     1120 <kernel_sgemm_nt_2x2_lib4+0x20>
addps  %xmm1,%xmm0
mov    %edi,%eax
and    $0xfffffffc,%eax
cmp    %edi,%eax
jl     11a3 <kernel_sgemm_nt_2x2_lib4+0xa3>
jmp    11db <kernel_sgemm_nt_2x2_lib4+0xdb>
xorps  %xmm0,%xmm0
xor    %eax,%eax
cmp    %edi,%eax
jge    11db <kernel_sgemm_nt_2x2_lib4+0xdb>
sub    %eax,%edi
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movaps %xmm0,%xmm1
movsd  (%rsi,%rax,1),%xmm0
movlhps %xmm0,%xmm0
movsd  (%rdx,%rax,1),%xmm2
unpcklps %xmm2,%xmm2
mulps  %xmm0,%xmm2
movaps %xmm2,%xmm0
addps  %xmm1,%xmm0
add    $0x10,%rax
add    $0xffffffff,%edi
jne    11b0 <kernel_sgemm_nt_2x2_lib4+0xb0>
addps  %xmm1,%xmm2
movaps %xmm2,%xmm0
test   %r9d,%r9d
je     11fd <kernel_sgemm_nt_2x2_lib4+0xfd>
movsd  (%rcx),%xmm1
movsd  0x10(%rcx),%xmm2
movlhps %xmm2,%xmm1
cmp    $0x1,%r9d
jne    11f7 <kernel_sgemm_nt_2x2_lib4+0xf7>
addps  %xmm1,%xmm0
jmp    11fd <kernel_sgemm_nt_2x2_lib4+0xfd>
subps  %xmm0,%xmm1
movaps %xmm1,%xmm0
movss  %xmm0,(%r8)
movaps %xmm0,%xmm1
shufps $0x55,%xmm0,%xmm1
movss  %xmm1,0x4(%r8)
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
movss  %xmm1,0x10(%r8)
shufps $0xff,%xmm0,%xmm0
movss  %xmm0,0x14(%r8)
ret

LLVM IR (-O0):
define void @kernel_sgemm_nt_2x2_lib4(i32 %0, float* %1, float* %2, float* %3, float* %4, i32 %5) {
%7 = alloca i32
%8 = alloca float*
%9 = alloca float*
%10 = alloca float*
%11 = alloca float*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%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
%25 = alloca float
%26 = alloca float
%27 = alloca float
store i32 %0, i32* %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
%28 = load i32, i32* %7
%29 = icmp sle i32 %28, 0
br i1 %29, label %30, label %31
30: ; preds = %6
br label %268
31: ; preds = %6
store i32 4, i32* %13
store i32 4, i32* %14
store float 0.000000e+00, float* %20
store float 0.000000e+00, float* %21
store float 0.000000e+00, float* %22
store float 0.000000e+00, float* %23
store i32 0, i32* %15
br label %32
32: ; preds = %154, %31
%33 = load i32, i32* %15
%34 = load i32, i32* %7
%35 = sub nsw i32 %34, 3
%36 = icmp slt i32 %33, %35
br i1 %36, label %37, label %157
37: ; preds = %32
%38 = load float*, float** %8
%39 = getelementptr inbounds float, float* %38, i64 0
%40 = load float, float* %39
store float %40, float* %16
%41 = load float*, float** %8
%42 = getelementptr inbounds float, float* %41, i64 1
%43 = load float, float* %42
store float %43, float* %17
%44 = load float*, float** %9
%45 = getelementptr inbounds float, float* %44, i64 0
%46 = load float, float* %45
store float %46, float* %18
%47 = load float*, float** %9
%48 = getelementptr inbounds float, float* %47, i64 1
%49 = load float, float* %48
store float %49, float* %19
%50 = load float, float* %16
%51 = load float, float* %18
%52 = load float, float* %20
%53 = call float @llvm.fmuladd.f32(float %50, float %51, float %52)
store float %53, float* %20
%54 = load float, float* %17
%55 = load float, float* %18
%56 = load float, float* %22
%57 = call float @llvm.fmuladd.f32(float %54, float %55, float %56)
store float %57, float* %22
%58 = load float, float* %16
%59 = load float, float* %19
%60 = load float, float* %21
%61 = call float @llvm.fmuladd.f32(float %58, float %59, float %60)
store float %61, float* %21
%62 = load float, float* %17
%63 = load float, float* %19
%64 = load float, float* %23
%65 = call float @llvm.fmuladd.f32(float %62, float %63, float %64)
store float %65, float* %23
%66 = load float*, float** %8
%67 = getelementptr inbounds float, float* %66, i64 4
%68 = load float, float* %67
store float %68, float* %16
%69 = load float*, float** %8
%70 = getelementptr inbounds float, float* %69, i64 5
%71 = load float, float* %70
store float %71, float* %17
%72 = load float*, float** %9
%73 = getelementptr inbounds float, float* %72, i64 4
%74 = load float, float* %73
store float %74, float* %18
%75 = load float*, float** %9
%76 = getelementptr inbounds float, float* %75, i64 5
%77 = load float, float* %76
store float %77, float* %19
%78 = load float, float* %16
%79 = load float, float* %18
%80 = load float, float* %20
%81 = call float @llvm.fmuladd.f32(float %78, float %79, float %80)
store float %81, float* %20
%82 = load float, float* %17
%83 = load float, float* %18
%84 = load float, float* %22
%85 = call float @llvm.fmuladd.f32(float %82, float %83, float %84)
store float %85, float* %22
%86 = load float, float* %16
%87 = load float, float* %19
%88 = load float, float* %21
%89 = call float @llvm.fmuladd.f32(float %86, float %87, float %88)
store float %89, float* %21
%90 = load float, float* %17
%91 = load float, float* %19
%92 = load float, float* %23
%93 = call float @llvm.fmuladd.f32(float %90, float %91, float %92)
store float %93, float* %23
%94 = load float*, float** %8
%95 = getelementptr inbounds float, float* %94, i64 8
%96 = load float, float* %95
store float %96, float* %16
%97 = load float*, float** %8
%98 = getelementptr inbounds float, float* %97, i64 9
%99 = load float, float* %98
store float %99, float* %17
%100 = load float*, float** %9
%101 = getelementptr inbounds float, float* %100, i64 8
%102 = load float, float* %101
store float %102, float* %18
%103 = load float*, float** %9
%104 = getelementptr inbounds float, float* %103, i64 9
%105 = load float, float* %104
store float %105, float* %19
%106 = load float, float* %16
%107 = load float, float* %18
%108 = load float, float* %20
%109 = call float @llvm.fmuladd.f32(float %106, float %107, float %108)
store float %109, float* %20
%110 = load float, float* %17
%111 = load float, float* %18
%112 = load float, float* %22
%113 = call float @llvm.fmuladd.f32(float %110, float %111, float %112)
store float %113, float* %22
%114 = load float, float* %16
%115 = load float, float* %19
%116 = load float, float* %21
%117 = call float @llvm.fmuladd.f32(float %114, float %115, float %116)
store float %117, float* %21
%118 = load float, float* %17
%119 = load float, float* %19
%120 = load float, float* %23
%121 = call float @llvm.fmuladd.f32(float %118, float %119, float %120)
store float %121, float* %23
%122 = load float*, float** %8
%123 = getelementptr inbounds float, float* %122, i64 12
%124 = load float, float* %123
store float %124, float* %16
%125 = load float*, float** %8
%126 = getelementptr inbounds float, float* %125, i64 13
%127 = load float, float* %126
store float %127, float* %17
%128 = load float*, float** %9
%129 = getelementptr inbounds float, float* %128, i64 12
%130 = load float, float* %129
store float %130, float* %18
%131 = load float*, float** %9
%132 = getelementptr inbounds float, float* %131, i64 13
%133 = load float, float* %132
store float %133, float* %19
%134 = load float, float* %16
%135 = load float, float* %18
%136 = load float, float* %20
%137 = call float @llvm.fmuladd.f32(float %134, float %135, float %136)
store float %137, float* %20
%138 = load float, float* %17
%139 = load float, float* %18
%140 = load float, float* %22
%141 = call float @llvm.fmuladd.f32(float %138, float %139, float %140)
store float %141, float* %22
%142 = load float, float* %16
%143 = load float, float* %19
%144 = load float, float* %21
%145 = call float @llvm.fmuladd.f32(float %142, float %143, float %144)
store float %145, float* %21
%146 = load float, float* %17
%147 = load float, float* %19
%148 = load float, float* %23
%149 = call float @llvm.fmuladd.f32(float %146, float %147, float %148)
store float %149, float* %23
%150 = load float*, float** %8
%151 = getelementptr inbounds float, float* %150, i64 16
store float* %151, float** %8
%152 = load float*, float** %9
%153 = getelementptr inbounds float, float* %152, i64 16
store float* %153, float** %9
br label %154
154: ; preds = %37
%155 = load i32, i32* %15
%156 = add nsw i32 %155, 4
store i32 %156, i32* %15
br label %32
157: ; preds = %32
br label %158
158: ; preds = %195, %157
%159 = load i32, i32* %15
%160 = load i32, i32* %7
%161 = icmp slt i32 %159, %160
br i1 %161, label %162, label %198
162: ; preds = %158
%163 = load float*, float** %8
%164 = getelementptr inbounds float, float* %163, i64 0
%165 = load float, float* %164
store float %165, float* %16
%166 = load float*, float** %8
%167 = getelementptr inbounds float, float* %166, i64 1
%168 = load float, float* %167
store float %168, float* %17
%169 = load float*, float** %9
%170 = getelementptr inbounds float, float* %169, i64 0
%171 = load float, float* %170
store float %171, float* %18
%172 = load float*, float** %9
%173 = getelementptr inbounds float, float* %172, i64 1
%174 = load float, float* %173
store float %174, float* %19
%175 = load float, float* %16
%176 = load float, float* %18
%177 = load float, float* %20
%178 = call float @llvm.fmuladd.f32(float %175, float %176, float %177)
store float %178, float* %20
%179 = load float, float* %17
%180 = load float, float* %18
%181 = load float, float* %22
%182 = call float @llvm.fmuladd.f32(float %179, float %180, float %181)
store float %182, float* %22
%183 = load float, float* %16
%184 = load float, float* %19
%185 = load float, float* %21
%186 = call float @llvm.fmuladd.f32(float %183, float %184, float %185)
store float %186, float* %21
%187 = load float, float* %17
%188 = load float, float* %19
%189 = load float, float* %23
%190 = call float @llvm.fmuladd.f32(float %187, float %188, float %189)
store float %190, float* %23
%191 = load float*, float** %8
%192 = getelementptr inbounds float, float* %191, i64 4
store float* %192, float** %8
%193 = load float*, float** %9
%194 = getelementptr inbounds float, float* %193, i64 4
store float* %194, float** %9
br label %195
195: ; preds = %162
%196 = load i32, i32* %15
%197 = add nsw i32 %196, 1
store i32 %197, i32* %15
br label %158
198: ; preds = %158
%199 = load i32, i32* %12
%200 = icmp eq i32 %199, 0
br i1 %200, label %201, label %214
201: ; preds = %198
%202 = load float, float* %20
%203 = load float*, float** %11
%204 = getelementptr inbounds float, float* %203, i64 0
store float %202, float* %204
%205 = load float, float* %22
%206 = load float*, float** %11
%207 = getelementptr inbounds float, float* %206, i64 1
store float %205, float* %207
%208 = load float, float* %21
%209 = load float*, float** %11
%210 = getelementptr inbounds float, float* %209, i64 4
store float %208, float* %210
%211 = load float, float* %23
%212 = load float*, float** %11
%213 = getelementptr inbounds float, float* %212, i64 5
store float %211, float* %213
br label %268
214: ; preds = %198
%215 = load float*, float** %10
%216 = getelementptr inbounds float, float* %215, i64 0
%217 = load float, float* %216
store float %217, float* %24
%218 = load float*, float** %10
%219 = getelementptr inbounds float, float* %218, i64 1
%220 = load float, float* %219
store float %220, float* %26
%221 = load float*, float** %10
%222 = getelementptr inbounds float, float* %221, i64 4
%223 = load float, float* %222
store float %223, float* %25
%224 = load float*, float** %10
%225 = getelementptr inbounds float, float* %224, i64 5
%226 = load float, float* %225
store float %226, float* %27
%227 = load i32, i32* %12
%228 = icmp eq i32 %227, 1
br i1 %228, label %229, label %242
229: ; preds = %214
%230 = load float, float* %20
%231 = load float, float* %24
%232 = fadd float %231, %230
store float %232, float* %24
%233 = load float, float* %22
%234 = load float, float* %26
%235 = fadd float %234, %233
store float %235, float* %26
%236 = load float, float* %21
%237 = load float, float* %25
%238 = fadd float %237, %236
store float %238, float* %25
%239 = load float, float* %23
%240 = load float, float* %27
%241 = fadd float %240, %239
store float %241, float* %27
br label %255
242: ; preds = %214
%243 = load float, float* %20
%244 = load float, float* %24
%245 = fsub float %244, %243
store float %245, float* %24
%246 = load float, float* %22
%247 = load float, float* %26
%248 = fsub float %247, %246
store float %248, float* %26
%249 = load float, float* %21
%250 = load float, float* %25
%251 = fsub float %250, %249
store float %251, float* %25
%252 = load float, float* %23
%253 = load float, float* %27
%254 = fsub float %253, %252
store float %254, float* %27
br label %255
255: ; preds = %242, %229
%256 = load float, float* %24
%257 = load float*, float** %11
%258 = getelementptr inbounds float, float* %257, i64 0
store float %256, float* %258
%259 = load float, float* %26
%260 = load float*, float** %11
%261 = getelementptr inbounds float, float* %260, i64 1
store float %259, float* %261
%262 = load float, float* %25
%263 = load float*, float** %11
%264 = getelementptr inbounds float, float* %263, i64 4
store float %262, float* %264
%265 = load float, float* %27
%266 = load float*, float** %11
%267 = getelementptr inbounds float, float* %266, i64 5
store float %265, float* %267
br label %268
268: ; preds = %30, %255, %201
ret void
}

LLVM IR (-O2):
define void @kernel_sgemm_nt_2x2_lib4(i32 %0, float* nocapture %1, float* nocapture %2, float* nocapture %3, float* nocapture writeonly %4, i32 %5) {
%7 = icmp slt i32 %0, 1
br i1 %7, label %109, label %8
8: ; preds = %6
%9 = add nsw i32 %0, -3
%10 = icmp ugt i32 %0, 3
br i1 %10, label %23, label %17
11: ; preds = %23
%12 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %30, <4 x float> %33, <4 x float> %27)
%13 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %38, <4 x float> %42, <4 x float> %12)
%14 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %47, <4 x float> %51, <4 x float> %13)
%15 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %56, <4 x float> %60, <4 x float> %14)
%16 = and i32 %0, -4
br label %17
17: ; preds = %11, %8
%18 = phi float* [ %2, %8 ], [ %63, %11 ]
%19 = phi float* [ %1, %8 ], [ %62, %11 ]
%20 = phi i32 [ 0, %8 ], [ %16, %11 ]
%21 = phi <4 x float> [ zeroinitializer, %8 ], [ %15, %11 ]
%22 = icmp slt i32 %20, %0
br i1 %22, label %66, label %84
23: ; preds = %8, %23
%24 = phi i32 [ %64, %23 ], [ 0, %8 ]
%25 = phi float* [ %62, %23 ], [ %1, %8 ]
%26 = phi float* [ %63, %23 ], [ %2, %8 ]
%27 = phi <4 x float> [ %61, %23 ], [ zeroinitializer, %8 ]
%28 = bitcast float* %25 to <2 x float>*
%29 = load <2 x float>, <2 x float>* %28
%30 = shufflevector <2 x float> %29, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%31 = bitcast float* %26 to <2 x float>*
%32 = load <2 x float>, <2 x float>* %31
%33 = shufflevector <2 x float> %32, <2 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%34 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %30, <4 x float> %33, <4 x float> %27)
%35 = getelementptr inbounds float, float* %25, i64 4
%36 = bitcast float* %35 to <2 x float>*
%37 = load <2 x float>, <2 x float>* %36
%38 = shufflevector <2 x float> %37, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%39 = getelementptr inbounds float, float* %26, i64 4
%40 = bitcast float* %39 to <2 x float>*
%41 = load <2 x float>, <2 x float>* %40
%42 = shufflevector <2 x float> %41, <2 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%43 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %38, <4 x float> %42, <4 x float> %34)
%44 = getelementptr inbounds float, float* %25, i64 8
%45 = bitcast float* %44 to <2 x float>*
%46 = load <2 x float>, <2 x float>* %45
%47 = shufflevector <2 x float> %46, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%48 = getelementptr inbounds float, float* %26, i64 8
%49 = bitcast float* %48 to <2 x float>*
%50 = load <2 x float>, <2 x float>* %49
%51 = shufflevector <2 x float> %50, <2 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%52 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %47, <4 x float> %51, <4 x float> %43)
%53 = getelementptr inbounds float, float* %25, i64 12
%54 = bitcast float* %53 to <2 x float>*
%55 = load <2 x float>, <2 x float>* %54
%56 = shufflevector <2 x float> %55, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%57 = getelementptr inbounds float, float* %26, i64 12
%58 = bitcast float* %57 to <2 x float>*
%59 = load <2 x float>, <2 x float>* %58
%60 = shufflevector <2 x float> %59, <2 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%61 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %56, <4 x float> %60, <4 x float> %52)
%62 = getelementptr inbounds float, float* %25, i64 16
%63 = getelementptr inbounds float, float* %26, i64 16
%64 = add nuw nsw i32 %24, 4
%65 = icmp slt i32 %64, %9
br i1 %65, label %23, label %11
66: ; preds = %17, %66
%67 = phi i32 [ %80, %66 ], [ %20, %17 ]
%68 = phi float* [ %78, %66 ], [ %19, %17 ]
%69 = phi float* [ %79, %66 ], [ %18, %17 ]
%70 = phi <4 x float> [ %77, %66 ], [ %21, %17 ]
%71 = bitcast float* %68 to <2 x float>*
%72 = load <2 x float>, <2 x float>* %71
%73 = shufflevector <2 x float> %72, <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%74 = bitcast float* %69 to <2 x float>*
%75 = load <2 x float>, <2 x float>* %74
%76 = shufflevector <2 x float> %75, <2 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%77 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %76, <4 x float> %70)
%78 = getelementptr inbounds float, float* %68, i64 4
%79 = getelementptr inbounds float, float* %69, i64 4
%80 = add nuw nsw i32 %67, 1
%81 = icmp eq i32 %80, %0
br i1 %81, label %82, label %66
82: ; preds = %66
%83 = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> %73, <4 x float> %76, <4 x float> %70)
br label %84
84: ; preds = %82, %17
%85 = phi <4 x float> [ %21, %17 ], [ %83, %82 ]
%86 = icmp eq i32 %5, 0
br i1 %86, label %100, label %87
87: ; preds = %84
%88 = bitcast float* %3 to <2 x float>*
%89 = load <2 x float>, <2 x float>* %88
%90 = getelementptr inbounds float, float* %3, i64 4
%91 = bitcast float* %90 to <2 x float>*
%92 = load <2 x float>, <2 x float>* %91
%93 = icmp eq i32 %5, 1
br i1 %93, label %94, label %97
94: ; preds = %87
%95 = shufflevector <2 x float> %89, <2 x float> %92, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
%96 = fadd <4 x float> %85, %95
br label %100
97: ; preds = %87
%98 = shufflevector <2 x float> %89, <2 x float> %92, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
%99 = fsub <4 x float> %98, %85
br label %100
100: ; preds = %94, %97, %84
%101 = phi <4 x float> [ %85, %84 ], [ %96, %94 ], [ %99, %97 ]
%102 = extractelement <4 x float> %101, i64 0
store float %102, float* %4
%103 = getelementptr inbounds float, float* %4, i64 1
%104 = extractelement <4 x float> %101, i64 1
store float %104, float* %103
%105 = getelementptr inbounds float, float* %4, i64 4
%106 = extractelement <4 x float> %101, i64 2
store float %106, float* %105
%107 = getelementptr inbounds float, float* %4, i64 5
%108 = extractelement <4 x float> %101, i64 3
store float %108, float* %107
br label %109
109: ; preds = %100, %6
ret void
}