void kernel_dgemm_nt_2x2_lib4(int kmax, double *A, double *B, double *C,
                              double *D, int alg) {
  if (kmax <= 0)
    return;
  const int lda = 4;
  const int ldc = 4;
  int k;
  double 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;
  }
  double 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] = c_00;
    C[1 + ldc * 0] = c_10;
    C[0 + ldc * 1] = c_01;
    C[1 + ldc * 1] = c_11;
  }
}


x86 assembly (clang, -O0):
<kernel_dgemm_nt_2x2_lib4>:
push   %rbp
mov    %rsp,%rbp
sub    $0x18,%rsp
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     112e <kernel_dgemm_nt_2x2_lib4+0x2e>
jmp    1691 <kernel_dgemm_nt_2x2_lib4+0x591>
movl   $0x4,-0x30(%rbp)
movl   $0x4,-0x34(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x70(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x78(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x3,%ecx
cmp    %ecx,%eax
jge    143c <kernel_dgemm_nt_2x2_lib4+0x33c>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x78(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x28(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x20(%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x28(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x78(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x40(%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x48(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x40(%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x48(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x78(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x60(%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x68(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x60(%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x68(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x78(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x80,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x80,%rax
mov    %rax,-0x18(%rbp)
mov    -0x38(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x38(%rbp)
jmp    1163 <kernel_dgemm_nt_2x2_lib4+0x63>
jmp    1441 <kernel_dgemm_nt_2x2_lib4+0x341>
mov    -0x38(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1519 <kernel_dgemm_nt_2x2_lib4+0x419>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x60(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x70(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
movsd  -0x78(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x18(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1441 <kernel_dgemm_nt_2x2_lib4+0x341>
cmpl   $0x0,-0x2c(%rbp)
jne    155f <kernel_dgemm_nt_2x2_lib4+0x45f>
movsd  -0x60(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x70(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x68(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x20(%rax)
movsd  -0x78(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x28(%rax)
jmp    1691 <kernel_dgemm_nt_2x2_lib4+0x591>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x80(%rbp)
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
mov    -0x28(%rbp),%rax
movsd  0x20(%rax),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
mov    -0x28(%rbp),%rax
movsd  0x28(%rax),%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
cmpl   $0x1,-0x2c(%rbp)
jne    15fc <kernel_dgemm_nt_2x2_lib4+0x4fc>
movsd  -0x60(%rbp),%xmm0
addsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x70(%rbp),%xmm0
addsd  -0x90(%rbp),%xmm0
ff
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x68(%rbp),%xmm0
addsd  -0x88(%rbp),%xmm0
ff
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x78(%rbp),%xmm0
addsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0x98(%rbp)
ff
jmp    165a <kernel_dgemm_nt_2x2_lib4+0x55a>
movsd  -0x60(%rbp),%xmm1
movsd  -0x80(%rbp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  -0x70(%rbp),%xmm1
movsd  -0x90(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x68(%rbp),%xmm1
movsd  -0x88(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  -0x78(%rbp),%xmm1
movsd  -0x98(%rbp),%xmm0
ff
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x60(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x70(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x68(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x20(%rax)
movsd  -0x78(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,0x28(%rax)
add    $0x18,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<kernel_dgemm_nt_2x2_lib4>:
test   %edi,%edi
jle    126a <kernel_dgemm_nt_2x2_lib4+0x16a>
cmp    $0x4,%edi
jb     11ef <kernel_dgemm_nt_2x2_lib4+0xef>
lea    -0x3(%rdi),%r8d
xorpd  %xmm3,%xmm3
xor    %eax,%eax
xorpd  %xmm5,%xmm5
nop
movupd (%rsi),%xmm4
movupd 0x20(%rsi),%xmm6
movupd 0x40(%rsi),%xmm9
movupd 0x60(%rsi),%xmm8
movsd  (%rdx),%xmm7
movsd  0x8(%rdx),%xmm2
movsd  0x20(%rdx),%xmm0
movsd  0x28(%rdx),%xmm1
unpcklpd %xmm7,%xmm7
mulpd  %xmm4,%xmm7
addpd  %xmm3,%xmm7
unpcklpd %xmm2,%xmm2
mulpd  %xmm4,%xmm2
addpd  %xmm5,%xmm2
unpcklpd %xmm0,%xmm0
mulpd  %xmm6,%xmm0
addpd  %xmm7,%xmm0
unpcklpd %xmm1,%xmm1
mulpd  %xmm6,%xmm1
addpd  %xmm2,%xmm1
movsd  0x40(%rdx),%xmm4
unpcklpd %xmm4,%xmm4
mulpd  %xmm9,%xmm4
addpd  %xmm0,%xmm4
movsd  0x48(%rdx),%xmm6
unpcklpd %xmm6,%xmm6
mulpd  %xmm9,%xmm6
addpd  %xmm1,%xmm6
movsd  0x60(%rdx),%xmm0
unpcklpd %xmm0,%xmm0
mulpd  %xmm8,%xmm0
movapd %xmm0,%xmm3
addpd  %xmm4,%xmm3
movsd  0x68(%rdx),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm8,%xmm1
movapd %xmm1,%xmm5
addpd  %xmm6,%xmm5
sub    $0xffffffffffffff80,%rsi
sub    $0xffffffffffffff80,%rdx
add    $0x4,%eax
cmp    %r8d,%eax
jl     1120 <kernel_dgemm_nt_2x2_lib4+0x20>
addpd  %xmm6,%xmm1
addpd  %xmm4,%xmm0
mov    %edi,%eax
and    $0xfffffffc,%eax
cmp    %edi,%eax
jl     11fd <kernel_dgemm_nt_2x2_lib4+0xfd>
jmp    1261 <kernel_dgemm_nt_2x2_lib4+0x161>
xorpd  %xmm0,%xmm0
xor    %eax,%eax
xorpd  %xmm1,%xmm1
cmp    %edi,%eax
jge    1261 <kernel_dgemm_nt_2x2_lib4+0x161>
sub    %eax,%edi
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movapd %xmm1,%xmm3
movapd %xmm0,%xmm2
movupd (%rsi,%rax,1),%xmm1
movsd  (%rdx,%rax,1),%xmm4
movsd  0x8(%rdx,%rax,1),%xmm5
unpcklpd %xmm4,%xmm4
mulpd  %xmm1,%xmm4
movapd %xmm4,%xmm0
addpd  %xmm2,%xmm0
unpcklpd %xmm5,%xmm5
mulpd  %xmm1,%xmm5
movapd %xmm5,%xmm1
addpd  %xmm3,%xmm1
add    $0x20,%rax
add    $0xffffffff,%edi
jne    1210 <kernel_dgemm_nt_2x2_lib4+0x110>
addpd  %xmm3,%xmm5
addpd  %xmm2,%xmm4
movapd %xmm4,%xmm0
movapd %xmm5,%xmm1
movupd %xmm0,(%rcx)
movupd %xmm1,0x20(%rcx)
ret

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

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