#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ assert(int);
int atoi(char *);
scalar_t__ malloc(int);
int /*<<< orphan*/ printf(char *);
int main(int argc, char **argv) {
  long **a, **b, **c;
  int N = 100;
  if (argc == 2) {
    N = atoi(argv[1]);
    assert(N > 0);
  }
  int i, j, k, mul = 5;
  int col_sum = N * (N - 1) / 2;
  a = (long **)malloc(N * sizeof(long *));
  b = (long **)malloc(N * sizeof(long *));
  c = (long **)malloc(N * sizeof(long *));
  for (i = 0; i < N; i++) {
    a[i] = (long *)malloc(N * sizeof(long));
    b[i] = (long *)malloc(N * sizeof(long));
    c[i] = (long *)malloc(N * sizeof(long));
  }
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++) {
      a[i][j] = i * mul;
      b[i][j] = i;
      c[i][j] = 0;
    }
  printf("Matrix generation finished.\n");
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      for (k = 0; k < N; k++)
        c[i][j] += a[i][k] * b[k][j];
  printf("Multiplication finished.\n");
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      assert(c[i][j] == i * mul * col_sum);
  printf("Test finished.\n");
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x64,-0x2c(%rbp)
cmpl   $0x2,-0x8(%rbp)
jne    1188 <main+0x48>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1060 <atoi@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
setg   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
movl   $0x5,-0x3c(%rbp)
mov    -0x2c(%rbp),%eax
mov    -0x2c(%rbp),%ecx
sub    $0x1,%ecx
imul   %ecx,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x40(%rbp)
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,-0x18(%rbp)
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,-0x20(%rbp)
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    125a <main+0x11a>
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x20(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
movslq -0x2c(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11e6 <main+0xa6>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    12ef <main+0x1af>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    12dc <main+0x19c>
mov    -0x30(%rbp),%eax
imul   -0x3c(%rbp),%eax
movslq %eax,%rdx
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
movslq -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
movq   $0x0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1274 <main+0x134>
jmp    12e1 <main+0x1a1>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1261 <main+0x121>
lea    0xd0a(%rip),%rdi
call   1030 <printf@plt>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    13a9 <main+0x269>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    1396 <main+0x256>
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    1383 <main+0x243>
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
imul   (%rax,%rcx,8),%rdx
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
add    (%rax,%rcx,8),%rdx
mov    %rdx,(%rax,%rcx,8)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1328 <main+0x1e8>
jmp    1388 <main+0x248>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1315 <main+0x1d5>
jmp    139b <main+0x25b>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1302 <main+0x1c2>
lea    0xc6d(%rip),%rdi
call   1030 <printf@plt>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    142e <main+0x2ee>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    141b <main+0x2db>
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%ecx
imul   -0x3c(%rbp),%ecx
imul   -0x40(%rbp),%ecx
movslq %ecx,%rcx
cmp    %rcx,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    13cf <main+0x28f>
jmp    1420 <main+0x2e0>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    13bc <main+0x27c>
lea    0xc02(%rip),%rdi
call   1030 <printf@plt>
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    $0x64,%ebx
cmp    $0x2,%edi
jne    1170 <main+0x30>
mov    0x8(%rsi),%rdi
call   1060 <atoi@plt>
mov    %eax,%ebx
xor    %edi,%edi
test   %eax,%eax
setg   %dil
call   1040 <assert@plt>
mov    %rbx,0x10(%rsp)
lea    0x0(,%rbx,8),%r13d
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    %rax,0x18(%rsp)
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    %rax,%r15
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    0x10(%rsp),%rcx
test   %ecx,%ecx
jle    1404 <main+0x2c4>
mov    %rax,%r12
lea    -0x1(%rcx),%eax
imul   %ecx,%eax
mov    %eax,%edx
shr    $0x1f,%edx
add    %eax,%edx
sar    %edx
mov    %rdx,0x20(%rsp)
mov    %ecx,%r14d
xor    %ebp,%ebp
mov    0x18(%rsp),%rbx
nopl   0x0(%rax,%rax,1)
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    %rax,(%rbx,%rbp,8)
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    %rax,(%r15,%rbp,8)
mov    %r13d,%edi
call   1050 <malloc@plt>
mov    %rax,(%r12,%rbp,8)
add    $0x1,%rbp
cmp    %rbp,%r14
jne    11d0 <main+0x90>
mov    0x10(%rsp),%r8
test   %r8d,%r8d
jle    1404 <main+0x2c4>
mov    %r14d,%eax
and    $0xfffffffc,%eax
mov    %rax,0x40(%rsp)
add    $0xfffffffffffffffc,%rax
mov    %rax,0x38(%rsp)
mov    %rax,%rcx
shr    $0x2,%rcx
add    $0x1,%rcx
lea    -0x1(%r14),%r13
mov    %rcx,%rax
mov    %rcx,0x30(%rsp)
and    $0xfffffffffffffffe,%rcx
mov    %rcx,0x28(%rsp)
xor    %edi,%edi
xorps  %xmm0,%xmm0
mov    0x18(%rsp),%rbx
jmp    125d <main+0x11d>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rdi
cmp    %r14,%rdi
je     1439 <main+0x2f9>
lea    (%rdi,%rdi,4),%r9d
mov    (%rbx,%rdi,8),%rcx
mov    (%r15,%rdi,8),%rdx
mov    (%r12,%rdi,8),%rax
cmp    $0x4,%r8d
jae    12d0 <main+0x190>
xor    %r11d,%r11d
mov    %r11,%rbp
test   $0x1,%r14b
je     1296 <main+0x156>
mov    %r9,(%rcx,%r11,8)
mov    %rdi,(%rdx,%r11,8)
movq   $0x0,(%rax,%r11,8)
mov    %r11,%rbp
or     $0x1,%rbp
cmp    %r11,%r13
je     1250 <main+0x110>
nopl   0x0(%rax,%rax,1)
mov    %r9,(%rcx,%rbp,8)
mov    %rdi,(%rdx,%rbp,8)
movq   $0x0,(%rax,%rbp,8)
mov    %r9,0x8(%rcx,%rbp,8)
mov    %rdi,0x8(%rdx,%rbp,8)
movq   $0x0,0x8(%rax,%rbp,8)
add    $0x2,%rbp
cmp    %rbp,%r14
jne    12a0 <main+0x160>
jmp    1250 <main+0x110>
xchg   %ax,%ax
lea    (%rcx,%r14,8),%rsi
lea    (%rdx,%r14,8),%rbp
lea    (%rax,%r14,8),%r8
cmp    %rbp,%rcx
setb   %bl
cmp    %rsi,%rdx
setb   %r10b
cmp    %r8,%rcx
setb   %r11b
cmp    %rsi,%rax
setb   0xf(%rsp)
cmp    %r8,%rdx
setb   %sil
cmp    %rbp,%rax
setb   %bpl
test   %r10b,%bl
jne    13e7 <main+0x2a7>
and    0xf(%rsp),%r11b
jne    13e7 <main+0x2a7>
mov    $0x0,%r11d
and    %bpl,%sil
mov    0x10(%rsp),%r8
mov    0x18(%rsp),%rbx
jne    1276 <main+0x136>
movq   %r9,%xmm1
pshufd $0x44,%xmm1,%xmm1
movq   %rdi,%xmm2
pshufd $0x44,%xmm2,%xmm2
cmpq   $0x0,0x38(%rsp)
je     13f9 <main+0x2b9>
mov    0x28(%rsp),%rsi
xor    %ebp,%ebp
nopw   0x0(%rax,%rax,1)
movdqu %xmm1,(%rcx,%rbp,8)
movdqu %xmm1,0x10(%rcx,%rbp,8)
movdqu %xmm2,(%rdx,%rbp,8)
movdqu %xmm2,0x10(%rdx,%rbp,8)
movups %xmm0,(%rax,%rbp,8)
movups %xmm0,0x10(%rax,%rbp,8)
movdqu %xmm1,0x20(%rcx,%rbp,8)
movdqu %xmm1,0x30(%rcx,%rbp,8)
movdqu %xmm2,0x20(%rdx,%rbp,8)
movdqu %xmm2,0x30(%rdx,%rbp,8)
movups %xmm0,0x20(%rax,%rbp,8)
movups %xmm0,0x30(%rax,%rbp,8)
add    $0x8,%rbp
add    $0xfffffffffffffffe,%rsi
jne    1360 <main+0x220>
testb  $0x1,0x30(%rsp)
je     13d1 <main+0x291>
movdqu %xmm1,(%rcx,%rbp,8)
movdqu %xmm1,0x10(%rcx,%rbp,8)
movdqu %xmm2,(%rdx,%rbp,8)
movdqu %xmm2,0x10(%rdx,%rbp,8)
movups %xmm0,(%rax,%rbp,8)
movups %xmm0,0x10(%rax,%rbp,8)
mov    0x40(%rsp),%rsi
mov    %rsi,%r11
cmp    %r14,%rsi
je     1250 <main+0x110>
jmp    1276 <main+0x136>
xor    %r11d,%r11d
mov    0x10(%rsp),%r8
mov    0x18(%rsp),%rbx
jmp    1276 <main+0x136>
xor    %ebp,%ebp
testb  $0x1,0x30(%rsp)
jne    13b2 <main+0x272>
jmp    13d1 <main+0x291>
lea    0xbf5(%rip),%rdi
call   1030 <puts@plt>
lea    0xc05(%rip),%rdi
call   1030 <puts@plt>
lea    0xc12(%rip),%rdi
call   1030 <puts@plt>
xor    %eax,%eax
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0xbc0(%rip),%rdi
call   1030 <puts@plt>
cmpl   $0x0,0x10(%rsp)
jle    1410 <main+0x2d0>
mov    %r14d,%eax
and    $0xfffffffe,%eax
xor    %r8d,%r8d
mov    0x18(%rsp),%r9
jmp    146d <main+0x32d>
nopl   0x0(%rax)
add    $0x1,%r8
cmp    %r14,%r8
je     14ef <main+0x3af>
mov    (%r9,%r8,8),%rdx
mov    (%r12,%r8,8),%rsi
xor    %edi,%edi
jmp    1489 <main+0x349>
nopl   0x0(%rax)
add    $0x1,%rdi
cmp    %r14,%rdi
je     1460 <main+0x320>
mov    (%rsi,%rdi,8),%rcx
xor    %ebp,%ebp
test   %r13,%r13
je     14d3 <main+0x393>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    (%r15,%rbp,8),%rbx
mov    (%rbx,%rdi,8),%rbx
imul   (%rdx,%rbp,8),%rbx
add    %rcx,%rbx
mov    %rbx,(%rsi,%rdi,8)
mov    0x8(%r15,%rbp,8),%rcx
mov    (%rcx,%rdi,8),%rcx
imul   0x8(%rdx,%rbp,8),%rcx
add    %rbx,%rcx
mov    %rcx,(%rsi,%rdi,8)
add    $0x2,%rbp
cmp    %rbp,%rax
jne    14a0 <main+0x360>
test   $0x1,%r14b
je     1480 <main+0x340>
mov    (%r15,%rbp,8),%rbx
mov    (%rbx,%rdi,8),%rbx
imul   (%rdx,%rbp,8),%rbx
add    %rbx,%rcx
mov    %rcx,(%rsi,%rdi,8)
jmp    1480 <main+0x340>
lea    0xb26(%rip),%rdi
call   1030 <puts@plt>
cmpl   $0x0,0x10(%rsp)
jle    141c <main+0x2dc>
mov    0x20(%rsp),%rax
lea    (%rax,%rax,4),%r15d
xor    %r13d,%r13d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %r15d,%eax
imul   %r13d,%eax
movslq %eax,%rbx
xor    %ebp,%ebp
nopl   0x0(%rax)
mov    (%r12,%r13,8),%rax
xor    %edi,%edi
cmp    %rbx,(%rax,%rbp,8)
sete   %dil
call   1040 <assert@plt>
add    $0x1,%rbp
cmp    %rbp,%r14
jne    1530 <main+0x3f0>
add    $0x1,%r13
cmp    %r14,%r13
jne    1520 <main+0x3e0>
jmp    141c <main+0x2dc>

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

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