void tiled_sgemm_tt(const int M, const int N, const int K, const float alpha,
                    const float *A, const int LDA, const float *B,
                    const int LDB, const float beta, float *C, const int LDC) {
#pragma omp target teams map(to : A[M * K], B[K * N]) map(from : C[M * N])
#pragma omp distribute collapse(2)
  for (int C_row_start = 0; C_row_start < M; C_row_start += 16)
    for (int C_col_start = 0; C_col_start < N; C_col_start += 16) {
      float As[16][16];
      float Bs[16][16];
#pragma omp parallel
      {
        int C_row, C_col;
        float Cval = 0.0;
        for (int kblock = 0; kblock < K; kblock += 16) {
#pragma omp for collapse(2)
          for (int row = 0; row < 16; row++)
            for (int col = 0; col < 16; col++) {
              C_row = C_row_start + row;
              C_col = C_col_start + col;
              if ((C_row < M) && (kblock + col < K))
                As[row][col] = A[(C_row * LDA) + kblock + col];
              else
                As[row][col] = 0;
              if ((kblock + row < K) && C_col < N)
                Bs[row][col] = B[((kblock + row) * LDB) + C_col];
              else
                Bs[row][col] = 0;
            }
#pragma omp for collapse(2)
          for (int row = 0; row < 16; row++)
            for (int col = 0; col < 16; col++) {
              for (int e = 0; e < 16; ++e)
                Cval += As[row][e] * Bs[e][col];
            }
        }
#pragma omp for collapse(2)
        for (int row = 0; row < 16; row++)
          for (int col = 0; col < 16; col++) {
            C_row = C_row_start + row;
            C_col = C_col_start + col;
            if ((C_row < M) && (C_col < N))
              C[(C_row * LDC) + C_col] =
                  alpha * Cval + beta * C[(C_row * LDC) + C_col];
          }
      }
    }
}


x86 assembly (clang, -O0):
<tiled_sgemm_tt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x7f0,%rsp
mov    0x20(%rbp),%eax
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%eax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
movss  %xmm0,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
mov    %r9,-0x28(%rbp)
movss  %xmm1,-0x2c(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    152e <tiled_sgemm_tt+0x42e>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    151b <tiled_sgemm_tt+0x41b>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x84c(%rbp)
ff
movl   $0x0,-0x850(%rbp)
mov    -0x850(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    141a <tiled_sgemm_tt+0x31a>
movl   $0x0,-0x854(%rbp)
cmpl   $0x10,-0x854(%rbp)
jge    131c <tiled_sgemm_tt+0x21c>
movl   $0x0,-0x858(%rbp)
cmpl   $0x10,-0x858(%rbp)
jge    1303 <tiled_sgemm_tt+0x203>
mov    -0x30(%rbp),%eax
add    -0x854(%rbp),%eax
mov    %eax,-0x844(%rbp)
mov    -0x34(%rbp),%eax
add    -0x858(%rbp),%eax
mov    %eax,-0x848(%rbp)
mov    -0x844(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1236 <tiled_sgemm_tt+0x136>
mov    -0x850(%rbp),%eax
add    -0x858(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1236 <tiled_sgemm_tt+0x136>
mov    -0x18(%rbp),%rax
mov    -0x844(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
add    -0x850(%rbp),%ecx
add    -0x858(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x854(%rbp),%rcx
lea    -0x440(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x858(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
jmp    125a <tiled_sgemm_tt+0x15a>
movslq -0x854(%rbp),%rcx
lea    -0x440(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x858(%rbp),%rcx
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x850(%rbp),%eax
add    -0x854(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    12c6 <tiled_sgemm_tt+0x1c6>
mov    -0x848(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    12c6 <tiled_sgemm_tt+0x1c6>
mov    -0x28(%rbp),%rax
mov    -0x850(%rbp),%ecx
add    -0x854(%rbp),%ecx
imul   0x10(%rbp),%ecx
add    -0x848(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x854(%rbp),%rcx
lea    -0x840(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x858(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
jmp    12ea <tiled_sgemm_tt+0x1ea>
movslq -0x854(%rbp),%rcx
lea    -0x840(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x858(%rbp),%rcx
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    12ef <tiled_sgemm_tt+0x1ef>
mov    -0x858(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x858(%rbp)
jmp    119f <tiled_sgemm_tt+0x9f>
jmp    1308 <tiled_sgemm_tt+0x208>
mov    -0x854(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x854(%rbp)
jmp    1188 <tiled_sgemm_tt+0x88>
movl   $0x0,-0x85c(%rbp)
cmpl   $0x10,-0x85c(%rbp)
jge    1401 <tiled_sgemm_tt+0x301>
movl   $0x0,-0x860(%rbp)
cmpl   $0x10,-0x860(%rbp)
jge    13e8 <tiled_sgemm_tt+0x2e8>
movl   $0x0,-0x864(%rbp)
cmpl   $0x10,-0x864(%rbp)
jge    13cf <tiled_sgemm_tt+0x2cf>
movslq -0x85c(%rbp),%rcx
lea    -0x440(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x864(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movslq -0x864(%rbp),%rcx
lea    -0x840(%rbp),%rax
shl    $0x6,%rcx
add    %rcx,%rax
movslq -0x860(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movss  -0x84c(%rbp),%xmm1
ff
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x84c(%rbp)
ff
mov    -0x864(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x864(%rbp)
jmp    1354 <tiled_sgemm_tt+0x254>
jmp    13d4 <tiled_sgemm_tt+0x2d4>
mov    -0x860(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x860(%rbp)
jmp    133d <tiled_sgemm_tt+0x23d>
jmp    13ed <tiled_sgemm_tt+0x2ed>
mov    -0x85c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x85c(%rbp)
jmp    1326 <tiled_sgemm_tt+0x226>
jmp    1406 <tiled_sgemm_tt+0x306>
mov    -0x850(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x850(%rbp)
jmp    116f <tiled_sgemm_tt+0x6f>
movl   $0x0,-0x868(%rbp)
cmpl   $0x10,-0x868(%rbp)
jge    1508 <tiled_sgemm_tt+0x408>
movl   $0x0,-0x86c(%rbp)
cmpl   $0x10,-0x86c(%rbp)
jge    14ef <tiled_sgemm_tt+0x3ef>
mov    -0x30(%rbp),%eax
add    -0x868(%rbp),%eax
mov    %eax,-0x844(%rbp)
mov    -0x34(%rbp),%eax
add    -0x86c(%rbp),%eax
mov    %eax,-0x848(%rbp)
mov    -0x844(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    14d6 <tiled_sgemm_tt+0x3d6>
mov    -0x848(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    14d6 <tiled_sgemm_tt+0x3d6>
movss  -0x10(%rbp),%xmm0
movss  -0x84c(%rbp),%xmm2
ff
movss  -0x2c(%rbp),%xmm1
mov    0x18(%rbp),%rax
mov    -0x844(%rbp),%ecx
imul   0x20(%rbp),%ecx
add    -0x848(%rbp),%ecx
movslq %ecx,%rcx
mulss  (%rax,%rcx,4),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    0x18(%rbp),%rax
mov    -0x844(%rbp),%ecx
imul   0x20(%rbp),%ecx
add    -0x848(%rbp),%ecx
movslq %ecx,%rcx
movss  %xmm0,(%rax,%rcx,4)
jmp    14db <tiled_sgemm_tt+0x3db>
mov    -0x86c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x86c(%rbp)
jmp    143b <tiled_sgemm_tt+0x33b>
jmp    14f4 <tiled_sgemm_tt+0x3f4>
mov    -0x868(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x868(%rbp)
jmp    1424 <tiled_sgemm_tt+0x324>
jmp    150d <tiled_sgemm_tt+0x40d>
mov    -0x34(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x34(%rbp)
jmp    114e <tiled_sgemm_tt+0x4e>
jmp    1520 <tiled_sgemm_tt+0x420>
mov    -0x30(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x30(%rbp)
jmp    113b <tiled_sgemm_tt+0x3b>
add    $0x7f0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<tiled_sgemm_tt>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x838,%rsp
mov    %r9,-0x38(%rsp)
mov    %rcx,0x28(%rsp)
mov    %edx,-0x74(%rsp)
mov    %esi,-0x78(%rsp)
test   %edi,%edi
jle    15e0 <tiled_sgemm_tt+0x4e0>
mov    0x878(%rsp),%rax
movslq -0x74(%rsp),%r10
movslq -0x78(%rsp),%rcx
mov    %rcx,-0x68(%rsp)
mov    %edi,%r14d
movslq 0x870(%rsp),%rcx
movslq 0x880(%rsp),%rdx
mov    %rcx,%rsi
shl    $0x6,%rsi
mov    %rsi,(%rsp)
shl    $0x2,%rcx
mov    %rcx,0x20(%rsp)
mov    %r8d,%ecx
mov    %rcx,0x18(%rsp)
shl    $0x4,%r8d
mov    %r8,-0x28(%rsp)
add    $0x4,%rax
mov    %rax,-0x40(%rsp)
mov    %rdx,%rax
shl    $0x6,%rax
mov    %rax,-0x30(%rsp)
shl    $0x2,%rdx
mov    %rdx,-0x20(%rsp)
xor    %eax,%eax
mov    %rax,-0x60(%rsp)
xor    %eax,%eax
mov    %rax,-0x70(%rsp)
movss  %xmm1,-0x50(%rsp)
movss  %xmm0,-0x54(%rsp)
jmp    11f3 <tiled_sgemm_tt+0xf3>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    -0x70(%rsp),%rcx
add    $0x10,%rcx
mov    -0x60(%rsp),%rax
add    -0x28(%rsp),%rax
mov    %rax,-0x60(%rsp)
mov    -0x30(%rsp),%rax
add    %rax,-0x40(%rsp)
mov    %rcx,%rax
mov    %rcx,-0x70(%rsp)
cmp    %r14,%rcx
jae    15e0 <tiled_sgemm_tt+0x4e0>
cmpl   $0x0,-0x78(%rsp)
jle    11c0 <tiled_sgemm_tt+0xc0>
mov    $0x1,%ebx
mov    -0x40(%rsp),%r8
mov    -0x38(%rsp),%r11
xor    %r12d,%r12d
jmp    122c <tiled_sgemm_tt+0x12c>
xchg   %ax,%ax
add    $0x10,%r12
mov    -0x18(%rsp),%r11
add    $0x40,%r11
add    $0x40,%r8
add    $0x10,%rbx
cmp    -0x68(%rsp),%r12
jge    11c0 <tiled_sgemm_tt+0xc0>
cmpl   $0x0,-0x74(%rsp)
mov    %rbx,-0x8(%rsp)
mov    %r8,-0x10(%rsp)
mov    %r11,-0x18(%rsp)
xorps  %xmm2,%xmm2
jle    154a <tiled_sgemm_tt+0x44a>
mov    -0x60(%rsp),%r15
xor    %r13d,%r13d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %r15,0x10(%rsp)
mov    %r11,0x8(%rsp)
lea    0x430(%rsp),%rsi
lea    0x30(%rsp),%rbp
xor    %r9d,%r9d
jmp    129c <tiled_sgemm_tt+0x19c>
nopl   0x0(%rax)
add    $0x1,%r9
add    $0x40,%rbp
add    $0x40,%rsi
add    0x20(%rsp),%r11
add    0x18(%rsp),%r15
cmp    $0x10,%r9
je     1310 <tiled_sgemm_tt+0x210>
mov    -0x70(%rsp),%rax
lea    (%r9,%rax,1),%rdi
lea    (%r9,%r13,1),%rax
xor    %edx,%edx
jmp    12c0 <tiled_sgemm_tt+0x1c0>
nopl   (%rax)
movss  %xmm4,0x0(%rbp,%rdx,4)
add    $0x1,%rdx
cmp    $0x10,%rdx
je     1280 <tiled_sgemm_tt+0x180>
xorps  %xmm4,%xmm4
xorps  %xmm3,%xmm3
cmp    %r14,%rdi
jae    12e8 <tiled_sgemm_tt+0x1e8>
lea    (%rdx,%r13,1),%r8
xorps  %xmm3,%xmm3
cmp    %r10,%r8
jge    12e8 <tiled_sgemm_tt+0x1e8>
lea    (%r15,%rdx,1),%ebx
movslq %ebx,%rbx
mov    0x28(%rsp),%rcx
movss  (%rcx,%rbx,4),%xmm3
movss  %xmm3,(%rsi,%rdx,4)
cmp    %r10,%rax
jge    12b0 <tiled_sgemm_tt+0x1b0>
lea    (%r12,%rdx,1),%rbx
cmp    -0x68(%rsp),%rbx
jge    12b0 <tiled_sgemm_tt+0x1b0>
movss  (%r11,%rdx,4),%xmm4
jmp    12b0 <tiled_sgemm_tt+0x1b0>
cs nopw 0x0(%rax,%rax,1)
nop
xor    %r9d,%r9d
mov    0x8(%rsp),%r11
nopl   0x0(%rax,%rax,1)
mov    %r9,%rax
shl    $0x6,%rax
movss  0x430(%rsp,%rax,1),%xmm0
movss  %xmm0,-0x44(%rsp)
movss  0x434(%rsp,%rax,1),%xmm0
movss  %xmm0,-0x48(%rsp)
movss  0x438(%rsp,%rax,1),%xmm0
movss  %xmm0,-0x4c(%rsp)
movss  0x43c(%rsp,%rax,1),%xmm11
movss  0x440(%rsp,%rax,1),%xmm12
movss  0x444(%rsp,%rax,1),%xmm13
movss  0x448(%rsp,%rax,1),%xmm14
movss  0x44c(%rsp,%rax,1),%xmm15
movss  0x450(%rsp,%rax,1),%xmm10
movss  0x454(%rsp,%rax,1),%xmm7
movss  0x458(%rsp,%rax,1),%xmm3
movss  0x45c(%rsp,%rax,1),%xmm4
movss  0x460(%rsp,%rax,1),%xmm5
movss  0x464(%rsp,%rax,1),%xmm8
movss  0x468(%rsp,%rax,1),%xmm1
movss  0x46c(%rsp,%rax,1),%xmm0
mov    $0xfffffffffffffff0,%r15
nopw   0x0(%rax,%rax,1)
movss  0x70(%rsp,%r15,4),%xmm9
mulss  -0x44(%rsp),%xmm9
addss  %xmm2,%xmm9
movss  0xb0(%rsp,%r15,4),%xmm2
mulss  -0x48(%rsp),%xmm2
addss  %xmm9,%xmm2
movss  0xf0(%rsp,%r15,4),%xmm6
mulss  -0x4c(%rsp),%xmm6
addss  %xmm2,%xmm6
movss  0x130(%rsp,%r15,4),%xmm2
mulss  %xmm11,%xmm2
addss  %xmm6,%xmm2
movss  0x170(%rsp,%r15,4),%xmm6
mulss  %xmm12,%xmm6
addss  %xmm2,%xmm6
movss  0x1b0(%rsp,%r15,4),%xmm2
mulss  %xmm13,%xmm2
addss  %xmm6,%xmm2
movss  0x1f0(%rsp,%r15,4),%xmm6
mulss  %xmm14,%xmm6
addss  %xmm2,%xmm6
movss  0x230(%rsp,%r15,4),%xmm2
mulss  %xmm15,%xmm2
addss  %xmm6,%xmm2
movss  0x270(%rsp,%r15,4),%xmm6
mulss  %xmm10,%xmm6
addss  %xmm2,%xmm6
movss  0x2b0(%rsp,%r15,4),%xmm2
mulss  %xmm7,%xmm2
addss  %xmm6,%xmm2
movss  0x2f0(%rsp,%r15,4),%xmm6
mulss  %xmm3,%xmm6
addss  %xmm2,%xmm6
movss  0x330(%rsp,%r15,4),%xmm2
mulss  %xmm4,%xmm2
addss  %xmm6,%xmm2
movss  0x370(%rsp,%r15,4),%xmm6
mulss  %xmm5,%xmm6
addss  %xmm2,%xmm6
movss  0x3b0(%rsp,%r15,4),%xmm2
mulss  %xmm8,%xmm2
addss  %xmm6,%xmm2
movss  0x3f0(%rsp,%r15,4),%xmm6
mulss  %xmm1,%xmm6
addss  %xmm2,%xmm6
movss  0x430(%rsp,%r15,4),%xmm2
mulss  %xmm0,%xmm2
addss  %xmm6,%xmm2
inc    %r15
jne    13e0 <tiled_sgemm_tt+0x2e0>
add    $0x1,%r9
cmp    $0x10,%r9
jne    1320 <tiled_sgemm_tt+0x220>
add    $0x10,%r13
add    (%rsp),%r11
mov    0x10(%rsp),%r15
add    $0x10,%r15
cmp    %r10,%r13
movss  -0x50(%rsp),%xmm1
movss  -0x54(%rsp),%xmm0
jl     1260 <tiled_sgemm_tt+0x160>
mov    -0x10(%rsp),%r8
mov    %r8,%rdx
xor    %esi,%esi
mov    -0x20(%rsp),%rcx
mov    -0x8(%rsp),%rbx
jmp    1571 <tiled_sgemm_tt+0x471>
add    $0x1,%rsi
add    %rcx,%rdx
cmp    $0x10,%rsi
je     1210 <tiled_sgemm_tt+0x110>
mov    -0x70(%rsp),%rax
add    %rsi,%rax
xor    %edi,%edi
jmp    158a <tiled_sgemm_tt+0x48a>
nopl   (%rax)
add    $0x2,%rdi
cmp    $0x10,%rdi
je     1560 <tiled_sgemm_tt+0x460>
cmp    %r14,%rax
jae    15b5 <tiled_sgemm_tt+0x4b5>
lea    (%r12,%rdi,1),%rbp
cmp    -0x68(%rsp),%rbp
jge    15b5 <tiled_sgemm_tt+0x4b5>
movss  -0x4(%rdx,%rdi,4),%xmm4
mulss  %xmm1,%xmm4
movaps %xmm0,%xmm3
mulss  %xmm2,%xmm3
addss  %xmm4,%xmm3
movss  %xmm3,-0x4(%rdx,%rdi,4)
cmp    %r14,%rax
jae    1580 <tiled_sgemm_tt+0x480>
lea    (%rbx,%rdi,1),%rbp
cmp    -0x68(%rsp),%rbp
jge    1580 <tiled_sgemm_tt+0x480>
movss  (%rdx,%rdi,4),%xmm4
mulss  %xmm1,%xmm4
movaps %xmm0,%xmm3
mulss  %xmm2,%xmm3
addss  %xmm4,%xmm3
movss  %xmm3,(%rdx,%rdi,4)
jmp    1580 <tiled_sgemm_tt+0x480>
add    $0x838,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @tiled_sgemm_tt(i32 %0, i32 %1, i32 %2, float %3, float* nocapture %4, i32 %5, float* nocapture %6, i32 %7, float %8, float* nocapture %9, i32 %10) {
%12 = alloca [16 x [16 x float]]
%13 = alloca [16 x [16 x float]]
%14 = icmp sgt i32 %0, 0
br i1 %14, label %15, label %27
15: ; preds = %11
%16 = icmp sgt i32 %1, 0
%17 = bitcast [16 x [16 x float]]* %12 to i8*
%18 = bitcast [16 x [16 x float]]* %13 to i8*
%19 = icmp sgt i32 %2, 0
%20 = sext i32 %2 to i64
%21 = sext i32 %1 to i64
%22 = zext i32 %0 to i64
%23 = sext i32 %7 to i64
%24 = sext i32 %10 to i64
br label %25
25: ; preds = %15, %28
%26 = phi i64 [ 0, %15 ], [ %29, %28 ]
br i1 %16, label %31, label %28
27: ; preds = %28, %11
ret void
28: ; preds = %175, %25
%29 = add nuw nsw i64 %26, 16
%30 = icmp ult i64 %29, %22
br i1 %30, label %25, label %27
31: ; preds = %25, %175
%32 = phi i64 [ %176, %175 ], [ 0, %25 ]
br i1 %19, label %35, label %33
33: ; preds = %111, %31
%34 = phi float [ 0.000000e+00, %31 ], [ %164, %111 ]
br label %170
35: ; preds = %31, %111
%36 = phi i64 [ %112, %111 ], [ 0, %31 ]
%37 = phi float [ %164, %111 ], [ 0.000000e+00, %31 ]
br label %38
38: ; preds = %35, %47
%39 = phi i64 [ 0, %35 ], [ %48, %47 ]
%40 = add nuw nsw i64 %39, %26
%41 = icmp ult i64 %40, %22
%42 = add nuw nsw i64 %39, %36
%43 = icmp slt i64 %42, %20
%44 = mul nsw i64 %42, %23
%45 = trunc i64 %40 to i32
%46 = mul i32 %45, %5
br label %50
47: ; preds = %71
%48 = add nuw nsw i64 %39, 1
%49 = icmp eq i64 %48, 16
br i1 %49, label %76, label %38
50: ; preds = %38, %71
%51 = phi i64 [ 0, %38 ], [ %74, %71 ]
%52 = add nuw nsw i64 %51, %32
%53 = add nuw nsw i64 %51, %36
%54 = icmp slt i64 %53, %20
%55 = select i1 %41, i1 %54, i1 false
br i1 %55, label %56, label %62
56: ; preds = %50
%57 = trunc i64 %53 to i32
%58 = add i32 %46, %57
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds float, float* %4, i64 %59
%61 = load float, float* %60
br label %62
62: ; preds = %50, %56
%63 = phi float [ %61, %56 ], [ 0.000000e+00, %50 ]
%64 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %39, i64 %51
store float %63, float* %64
%65 = icmp slt i64 %52, %21
%66 = select i1 %43, i1 %65, i1 false
br i1 %66, label %67, label %71
67: ; preds = %62
%68 = add nsw i64 %52, %44
%69 = getelementptr inbounds float, float* %6, i64 %68
%70 = load float, float* %69
br label %71
71: ; preds = %62, %67
%72 = phi float [ %70, %67 ], [ 0.000000e+00, %62 ]
%73 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 %39, i64 %51
store float %72, float* %73
%74 = add nuw nsw i64 %51, 1
%75 = icmp eq i64 %74, 16
br i1 %75, label %47, label %50
76: ; preds = %47, %167
%77 = phi i64 [ %168, %167 ], [ 0, %47 ]
%78 = phi float [ %164, %167 ], [ %37, %47 ]
%79 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 0
%80 = load float, float* %79
%81 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 1
%82 = load float, float* %81
%83 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 2
%84 = load float, float* %83
%85 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 3
%86 = load float, float* %85
%87 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 4
%88 = load float, float* %87
%89 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 5
%90 = load float, float* %89
%91 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 6
%92 = load float, float* %91
%93 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 7
%94 = load float, float* %93
%95 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 8
%96 = load float, float* %95
%97 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 9
%98 = load float, float* %97
%99 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 10
%100 = load float, float* %99
%101 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 11
%102 = load float, float* %101
%103 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 12
%104 = load float, float* %103
%105 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 13
%106 = load float, float* %105
%107 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 14
%108 = load float, float* %107
%109 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %12, i64 0, i64 %77, i64 15
%110 = load float, float* %109
br label %114
111: ; preds = %167
%112 = add nuw nsw i64 %36, 16
%113 = icmp slt i64 %112, %20
br i1 %113, label %35, label %33
114: ; preds = %76, %114
%115 = phi i64 [ 0, %76 ], [ %165, %114 ]
%116 = phi float [ %78, %76 ], [ %164, %114 ]
%117 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 0, i64 %115
%118 = load float, float* %117
%119 = tail call float @llvm.fmuladd.f32(float %80, float %118, float %116)
%120 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 1, i64 %115
%121 = load float, float* %120
%122 = tail call float @llvm.fmuladd.f32(float %82, float %121, float %119)
%123 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 2, i64 %115
%124 = load float, float* %123
%125 = tail call float @llvm.fmuladd.f32(float %84, float %124, float %122)
%126 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 3, i64 %115
%127 = load float, float* %126
%128 = tail call float @llvm.fmuladd.f32(float %86, float %127, float %125)
%129 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 4, i64 %115
%130 = load float, float* %129
%131 = tail call float @llvm.fmuladd.f32(float %88, float %130, float %128)
%132 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 5, i64 %115
%133 = load float, float* %132
%134 = tail call float @llvm.fmuladd.f32(float %90, float %133, float %131)
%135 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 6, i64 %115
%136 = load float, float* %135
%137 = tail call float @llvm.fmuladd.f32(float %92, float %136, float %134)
%138 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 7, i64 %115
%139 = load float, float* %138
%140 = tail call float @llvm.fmuladd.f32(float %94, float %139, float %137)
%141 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 8, i64 %115
%142 = load float, float* %141
%143 = tail call float @llvm.fmuladd.f32(float %96, float %142, float %140)
%144 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 9, i64 %115
%145 = load float, float* %144
%146 = tail call float @llvm.fmuladd.f32(float %98, float %145, float %143)
%147 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 10, i64 %115
%148 = load float, float* %147
%149 = tail call float @llvm.fmuladd.f32(float %100, float %148, float %146)
%150 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 11, i64 %115
%151 = load float, float* %150
%152 = tail call float @llvm.fmuladd.f32(float %102, float %151, float %149)
%153 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 12, i64 %115
%154 = load float, float* %153
%155 = tail call float @llvm.fmuladd.f32(float %104, float %154, float %152)
%156 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 13, i64 %115
%157 = load float, float* %156
%158 = tail call float @llvm.fmuladd.f32(float %106, float %157, float %155)
%159 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 14, i64 %115
%160 = load float, float* %159
%161 = tail call float @llvm.fmuladd.f32(float %108, float %160, float %158)
%162 = getelementptr inbounds [16 x [16 x float]], [16 x [16 x float]]* %13, i64 0, i64 15, i64 %115
%163 = load float, float* %162
%164 = tail call float @llvm.fmuladd.f32(float %110, float %163, float %161)
%165 = add nuw nsw i64 %115, 1
%166 = icmp eq i64 %165, 16
br i1 %166, label %167, label %114
167: ; preds = %114
%168 = add nuw nsw i64 %77, 1
%169 = icmp eq i64 %168, 16
br i1 %169, label %111, label %76
170: ; preds = %33, %178
%171 = phi i64 [ 0, %33 ], [ %179, %178 ]
%172 = add nuw nsw i64 %171, %26
%173 = icmp ult i64 %172, %22
%174 = mul nsw i64 %172, %24
br label %181
175: ; preds = %178
%176 = add nuw nsw i64 %32, 16
%177 = icmp slt i64 %176, %21
br i1 %177, label %31, label %28
178: ; preds = %203
%179 = add nuw nsw i64 %171, 1
%180 = icmp eq i64 %179, 16
br i1 %180, label %175, label %170
181: ; preds = %203, %170
%182 = phi i64 [ 0, %170 ], [ %204, %203 ]
%183 = add nuw nsw i64 %182, %32
%184 = icmp slt i64 %183, %21
%185 = select i1 %173, i1 %184, i1 false
br i1 %185, label %186, label %192
186: ; preds = %181
%187 = add nsw i64 %183, %174
%188 = getelementptr inbounds float, float* %9, i64 %187
%189 = load float, float* %188
%190 = fmul float %189, %8
%191 = tail call float @llvm.fmuladd.f32(float %3, float %34, float %190)
store float %191, float* %188
br label %192
192: ; preds = %181, %186
%193 = or i64 %182, 1
%194 = add nuw nsw i64 %193, %32
%195 = icmp slt i64 %194, %21
%196 = select i1 %173, i1 %195, i1 false
br i1 %196, label %197, label %203
197: ; preds = %192
%198 = add nsw i64 %194, %174
%199 = getelementptr inbounds float, float* %9, i64 %198
%200 = load float, float* %199
%201 = fmul float %200, %8
%202 = tail call float @llvm.fmuladd.f32(float %3, float %34, float %201)
store float %202, float* %199
br label %203
203: ; preds = %197, %192
%204 = add nuw nsw i64 %182, 2
%205 = icmp eq i64 %204, 16
br i1 %205, label %178, label %181
}