#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 */
typedef scalar_t__ clock_t;

/* Variables and functions */
double CLOCKS_PER_SEC;
int RAND_MAX;
double *calloc(int, int);
scalar_t__ clock();
int /*<<< orphan*/ dgemm_(char *, char *, int *, int *, int *, double *,
                          double *, int *, double *, int *, double *, double *,
                          int *);
int /*<<< orphan*/ printf(char *, double);
int rand();
int /*<<< orphan*/ sscanf(char *, char *, int *);
int main(int argc, char **argv) {
  clock_t begin, end;
  double time_passed;
  begin = clock();
  int i, j, k, N;
  double *A, *B, s;
  sscanf(argv[1], "%u", &N);
  A = calloc(N * N, sizeof(double));
  B = calloc(N * N, sizeof(double));
  double uno = 1, zero = 0;
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
      A[i + j * N] = 1. * rand() / RAND_MAX;
    }
  }
  end = clock();
  time_passed = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("Tempo di creazione di A: %f s\n", time_passed);
  begin = end;
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
      B[i + j * N] = 0.;
      for (k = 0; k < N; k++) {
        B[i + j * N] += A[i + k * N] * A[k + j * N];
      }
      s += B[i + j * N];
    }
  }
  printf("%f\n", s);
  end = clock();
  time_passed = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("Tempo di moltiplicazione di A: %f s\n", time_passed);
  begin = end;
  dgemm_("N", "N", &N, &N, &N, &uno, A, &N, A, &N, &zero, B, &N);
  end = clock();
  time_passed = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("Tempo di moltiplicazione A con blas: %f s\n", time_passed);
  for (i = 0; i < N * N; i++)
    s += B[i];
  printf("%f\n", s);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
push   %r14
push   %rbx
sub    $0xa0,%rsp
movl   $0x0,-0x14(%rbp)
mov    %edi,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xe72(%rip),%rsi
lea    -0x48(%rbp),%rdx
call   1070 <sscanf@plt>
mov    -0x48(%rbp),%edi
imul   -0x48(%rbp),%edi
mov    $0x8,%esi
call   1060 <calloc@plt>
mov    %rax,-0x50(%rbp)
mov    -0x48(%rbp),%edi
imul   -0x48(%rbp),%edi
mov    $0x8,%esi
call   1060 <calloc@plt>
mov    %rax,-0x58(%rbp)
movsd  0xe2f(%rip),%xmm0
movsd  %xmm0,-0x68(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x70(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x48(%rbp),%eax
jge    1263 <main+0x103>
movl   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%eax
cmp    -0x48(%rbp),%eax
jge    1250 <main+0xf0>
mov    $0x0,%al
call   1080 <rand@plt>
cvtsi2sd %eax,%xmm1
movsd  0xde9(%rip),%xmm0
mulsd  %xmm1,%xmm0
mov    0x2dbe(%rip),%rax
cvtsi2sdl (%rax),%xmm1
divsd  %xmm1,%xmm0
mov    -0x50(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x40(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
jmp    11f8 <main+0x98>
jmp    1255 <main+0xf5>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    11e5 <main+0x85>
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
sub    -0x28(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2d66(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
lea    0xd74(%rip),%rdi
call   1050 <printf@plt>
mov    -0x30(%rbp),%rax
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x48(%rbp),%eax
jge    139e <main+0x23e>
movl   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%eax
cmp    -0x48(%rbp),%eax
jge    138b <main+0x22b>
mov    -0x58(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x40(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x48(%rbp),%eax
jge    135b <main+0x1fb>
mov    -0x50(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x44(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x44(%rbp),%ecx
mov    -0x40(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x58(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x40(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    12ec <main+0x18c>
mov    -0x58(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x40(%rbp),%edx
imul   -0x48(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x40(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
jmp    12be <main+0x15e>
jmp    1390 <main+0x230>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    12ab <main+0x14b>
movsd  -0x60(%rbp),%xmm0
lea    0xc80(%rip),%rdi
call   1050 <printf@plt>
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
sub    -0x28(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2c1a(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
lea    0xc4b(%rip),%rdi
call   1050 <printf@plt>
mov    -0x30(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x50(%rbp),%r14
mov    -0x50(%rbp),%rbx
mov    -0x58(%rbp),%r10
lea    0xc50(%rip),%rsi
lea    -0x48(%rbp),%rax
lea    -0x68(%rbp),%r9
lea    -0x70(%rbp),%r11
mov    %rsi,%rdi
mov    %rax,%rdx
mov    %rax,%rcx
mov    %rax,%r8
mov    %r14,(%rsp)
mov    %rax,0x8(%rsp)
mov    %rbx,0x10(%rsp)
mov    %rax,0x18(%rsp)
mov    %r11,0x20(%rsp)
mov    %r10,0x28(%rsp)
mov    %rax,0x30(%rsp)
call   1040 <dgemm_@plt>
mov    $0x0,%al
call   1030 <clock@plt>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
sub    -0x28(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2b87(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x38(%rbp),%xmm0
lea    0xbdf(%rip),%rdi
call   1050 <printf@plt>
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
mov    -0x48(%rbp),%ecx
imul   -0x48(%rbp),%ecx
cmp    %ecx,%eax
jge    14b9 <main+0x359>
mov    -0x58(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1482 <main+0x322>
movsd  -0x60(%rbp),%xmm0
lea    0xb65(%rip),%rdi
call   1050 <printf@plt>
xor    %eax,%eax
add    $0xa0,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rsi,%rbx
xor    %eax,%eax
call   1030 <clock@plt>
mov    %rax,0x8(%rsp)
mov    0x8(%rbx),%rdi
lea    0xe78(%rip),%rsi
lea    0x4(%rsp),%rdx
call   1070 <sscanf@plt>
mov    0x4(%rsp),%ebx
mov    %ebx,%ebp
imul   %ebx,%ebp
mov    %ebp,%edi
mov    $0x8,%esi
call   1060 <calloc@plt>
mov    %rax,%r14
mov    %ebp,%edi
mov    $0x8,%esi
call   1060 <calloc@plt>
mov    %rax,%r15
movabs $0x3ff0000000000000,%rax
mov    %rax,0x20(%rsp)
movq   $0x0,0x18(%rsp)
test   %ebx,%ebx
jle    122a <main+0xca>
mov    0x2e04(%rip),%r12
xor    %ebp,%ebp
jmp    11e7 <main+0x87>
add    $0x1,%ebp
cmp    %ebx,%ebp
jge    122a <main+0xca>
test   %ebx,%ebx
jle    11e0 <main+0x80>
xor    %r13d,%r13d
xchg   %ax,%ax
xor    %eax,%eax
call   1080 <rand@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
xorps  %xmm1,%xmm1
cvtsi2sdl (%r12),%xmm1
divsd  %xmm1,%xmm0
mov    0x4(%rsp),%ebx
mov    %ebx,%eax
imul   %r13d,%eax
add    %ebp,%eax
cltq
movsd  %xmm0,(%r14,%rax,8)
add    $0x1,%r13d
cmp    %ebx,%r13d
jl     11f0 <main+0x90>
jmp    11e0 <main+0x80>
xor    %eax,%eax
call   1030 <clock@plt>
mov    %rax,0x10(%rsp)
sub    0x8(%rsp),%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x2d9e(%rip),%rax
divsd  (%rax),%xmm0
lea    0xdae(%rip),%rdi
call   1050 <printf@plt>
mov    0x4(%rsp),%r11d
test   %r11d,%r11d
jle    1348 <main+0x1e8>
mov    %r11d,%ecx
and    $0xfffffffe,%ecx
lea    0x0(,%r11,8),%rdx
mov    %r11,%rsi
shl    $0x4,%rsi
mov    %r14,%r8
add    $0x8,%r8
xor    %r10d,%r10d
mov    %r14,%r9
jmp    12a1 <main+0x141>
nopl   0x0(%rax)
add    $0x1,%r10
add    $0x8,%r9
cmp    %r11,%r10
je     1348 <main+0x1e8>
mov    %r8,%rdi
xor    %ebx,%ebx
jmp    12c6 <main+0x166>
nopl   0x0(%rax,%rax,1)
movsd  %xmm2,(%r15,%rbp,8)
addsd  %xmm2,%xmm0
add    $0x1,%rbx
add    %rdx,%rdi
cmp    %r11,%rbx
je     1290 <main+0x130>
mov    %rbx,%r13
imul   %r11,%r13
xorpd  %xmm2,%xmm2
cmp    $0x1,%r11d
jne    12e0 <main+0x180>
xor    %r12d,%r12d
jmp    131c <main+0x1bc>
nopl   0x0(%rax)
mov    %r9,%rbp
xor    %r12d,%r12d
cs nopw 0x0(%rax,%rax,1)
movsd  0x0(%rbp),%xmm1
mulsd  -0x8(%rdi,%r12,8),%xmm1
addsd  %xmm2,%xmm1
movsd  0x0(%rbp,%rdx,1),%xmm2
mulsd  (%rdi,%r12,8),%xmm2
addsd  %xmm1,%xmm2
add    $0x2,%r12
add    %rsi,%rbp
cmp    %r12,%rcx
jne    12f0 <main+0x190>
lea    (%r10,%r13,1),%rbp
test   $0x1,%r11b
je     12b0 <main+0x150>
mov    %r12,%rax
imul   %r11,%rax
add    %r10,%rax
movsd  (%r14,%rax,8),%xmm1
add    %r12,%r13
mulsd  (%r14,%r13,8),%xmm1
addsd  %xmm1,%xmm2
jmp    12b0 <main+0x150>
lea    0xcd3(%rip),%rdi
movsd  %xmm0,0x8(%rsp)
call   1050 <printf@plt>
xor    %eax,%eax
call   1030 <clock@plt>
mov    %rax,%r13
sub    0x10(%rsp),%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x2c70(%rip),%rbx
divsd  (%rbx),%xmm0
lea    0xca3(%rip),%rdi
call   1050 <printf@plt>
sub    $0x8,%rsp
lea    0x20(%rsp),%rax
lea    0xcb3(%rip),%rdi
lea    0x28(%rsp),%r9
mov    %rdi,%rsi
lea    0xc(%rsp),%rcx
mov    %rcx,%rdx
mov    %rcx,%r8
push   %rcx
push   %r15
push   %rax
push   %rcx
push   %r14
push   %rcx
push   %r14
call   1040 <dgemm_@plt>
add    $0x40,%rsp
xor    %eax,%eax
call   1030 <clock@plt>
sub    %r13,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
divsd  (%rbx),%xmm0
lea    0xc72(%rip),%rdi
call   1050 <printf@plt>
mov    0x4(%rsp),%eax
imul   %eax,%eax
test   %eax,%eax
je     1406 <main+0x2a6>
mov    %eax,%edx
lea    -0x1(%rdx),%rcx
mov    %edx,%eax
and    $0x7,%eax
cmp    $0x7,%rcx
jae    140e <main+0x2ae>
xor    %ecx,%ecx
movsd  0x8(%rsp),%xmm0
jmp    1460 <main+0x300>
movsd  0x8(%rsp),%xmm0
jmp    147e <main+0x31e>
and    $0xfffffff8,%edx
xor    %ecx,%ecx
movsd  0x8(%rsp),%xmm0
nopl   0x0(%rax)
addsd  (%r15,%rcx,8),%xmm0
addsd  0x8(%r15,%rcx,8),%xmm0
addsd  0x10(%r15,%rcx,8),%xmm0
addsd  0x18(%r15,%rcx,8),%xmm0
addsd  0x20(%r15,%rcx,8),%xmm0
addsd  0x28(%r15,%rcx,8),%xmm0
addsd  0x30(%r15,%rcx,8),%xmm0
addsd  0x38(%r15,%rcx,8),%xmm0
add    $0x8,%rcx
cmp    %rcx,%rdx
jne    1420 <main+0x2c0>
test   %rax,%rax
je     147e <main+0x31e>
lea    (%r15,%rcx,8),%rcx
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
addsd  (%rcx,%rdx,8),%xmm0
add    $0x1,%rdx
cmp    %rdx,%rax
jne    1470 <main+0x310>
lea    0xb9d(%rip),%rdi
call   1050 <printf@plt>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [3 x i8] c"%u\00"
@RAND_MAX = global i32 0
@CLOCKS_PER_SEC = global double 0.000000e+00
@.str.1 = [31 x i8] c"Tempo di creazione di A: %f s\0A\00"
@.str.2 = [4 x i8] c"%f\0A\00"
@.str.3 = [37 x i8] c"Tempo di moltiplicazione di A: %f s\0A\00"
@.str.4 = [2 x i8] c"N\00"
@.str.5 = [43 x i8] c"Tempo di moltiplicazione A con blas: %f s\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 double
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca double*
%14 = alloca double*
%15 = alloca double
%16 = alloca double
%17 = alloca double
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%18 = call i64 (...) @clock()
store i64 %18, i64* %6
%19 = load i8**, i8*** %5
%20 = getelementptr inbounds i8*, i8** %19, i64 1
%21 = load i8*, i8** %20
%22 = call i32 @sscanf(i8* %21, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32* %12)
%23 = load i32, i32* %12
%24 = load i32, i32* %12
%25 = mul nsw i32 %23, %24
%26 = call double* @calloc(i32 %25, i32 8)
store double* %26, double** %13
%27 = load i32, i32* %12
%28 = load i32, i32* %12
%29 = mul nsw i32 %27, %28
%30 = call double* @calloc(i32 %29, i32 8)
store double* %30, double** %14
store double 1.000000e+00, double* %16
store double 0.000000e+00, double* %17
store i32 0, i32* %9
br label %31
31: ; preds = %59, %2
%32 = load i32, i32* %9
%33 = load i32, i32* %12
%34 = icmp slt i32 %32, %33
br i1 %34, label %35, label %62
35: ; preds = %31
store i32 0, i32* %10
br label %36
36: ; preds = %55, %35
%37 = load i32, i32* %10
%38 = load i32, i32* %12
%39 = icmp slt i32 %37, %38
br i1 %39, label %40, label %58
40: ; preds = %36
%41 = call i32 (...) @rand()
%42 = sitofp i32 %41 to double
%43 = fmul double 1.000000e+00, %42
%44 = load i32, i32* @RAND_MAX
%45 = sitofp i32 %44 to double
%46 = fdiv double %43, %45
%47 = load double*, double** %13
%48 = load i32, i32* %9
%49 = load i32, i32* %10
%50 = load i32, i32* %12
%51 = mul nsw i32 %49, %50
%52 = add nsw i32 %48, %51
%53 = sext i32 %52 to i64
%54 = getelementptr inbounds double, double* %47, i64 %53
store double %46, double* %54
br label %55
55: ; preds = %40
%56 = load i32, i32* %10
%57 = add nsw i32 %56, 1
store i32 %57, i32* %10
br label %36
58: ; preds = %36
br label %59
59: ; preds = %58
%60 = load i32, i32* %9
%61 = add nsw i32 %60, 1
store i32 %61, i32* %9
br label %31
62: ; preds = %31
%63 = call i64 (...) @clock()
store i64 %63, i64* %7
%64 = load i64, i64* %7
%65 = load i64, i64* %6
%66 = sub nsw i64 %64, %65
%67 = sitofp i64 %66 to double
%68 = load double, double* @CLOCKS_PER_SEC
%69 = fdiv double %67, %68
store double %69, double* %8
%70 = load double, double* %8
%71 = call i32 @printf(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.1, i64 0, i64 0), double %70)
%72 = load i64, i64* %7
store i64 %72, i64* %6
store i32 0, i32* %9
br label %73
73: ; preds = %143, %62
%74 = load i32, i32* %9
%75 = load i32, i32* %12
%76 = icmp slt i32 %74, %75
br i1 %76, label %77, label %146
77: ; preds = %73
store i32 0, i32* %10
br label %78
78: ; preds = %139, %77
%79 = load i32, i32* %10
%80 = load i32, i32* %12
%81 = icmp slt i32 %79, %80
br i1 %81, label %82, label %142
82: ; preds = %78
%83 = load double*, double** %14
%84 = load i32, i32* %9
%85 = load i32, i32* %10
%86 = load i32, i32* %12
%87 = mul nsw i32 %85, %86
%88 = add nsw i32 %84, %87
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds double, double* %83, i64 %89
store double 0.000000e+00, double* %90
store i32 0, i32* %11
br label %91
91: ; preds = %124, %82
%92 = load i32, i32* %11
%93 = load i32, i32* %12
%94 = icmp slt i32 %92, %93
br i1 %94, label %95, label %127
95: ; preds = %91
%96 = load double*, double** %13
%97 = load i32, i32* %9
%98 = load i32, i32* %11
%99 = load i32, i32* %12
%100 = mul nsw i32 %98, %99
%101 = add nsw i32 %97, %100
%102 = sext i32 %101 to i64
%103 = getelementptr inbounds double, double* %96, i64 %102
%104 = load double, double* %103
%105 = load double*, double** %13
%106 = load i32, i32* %11
%107 = load i32, i32* %10
%108 = load i32, i32* %12
%109 = mul nsw i32 %107, %108
%110 = add nsw i32 %106, %109
%111 = sext i32 %110 to i64
%112 = getelementptr inbounds double, double* %105, i64 %111
%113 = load double, double* %112
%114 = load double*, double** %14
%115 = load i32, i32* %9
%116 = load i32, i32* %10
%117 = load i32, i32* %12
%118 = mul nsw i32 %116, %117
%119 = add nsw i32 %115, %118
%120 = sext i32 %119 to i64
%121 = getelementptr inbounds double, double* %114, i64 %120
%122 = load double, double* %121
%123 = call double @llvm.fmuladd.f64(double %104, double %113, double %122)
store double %123, double* %121
br label %124
124: ; preds = %95
%125 = load i32, i32* %11
%126 = add nsw i32 %125, 1
store i32 %126, i32* %11
br label %91
127: ; preds = %91
%128 = load double*, double** %14
%129 = load i32, i32* %9
%130 = load i32, i32* %10
%131 = load i32, i32* %12
%132 = mul nsw i32 %130, %131
%133 = add nsw i32 %129, %132
%134 = sext i32 %133 to i64
%135 = getelementptr inbounds double, double* %128, i64 %134
%136 = load double, double* %135
%137 = load double, double* %15
%138 = fadd double %137, %136
store double %138, double* %15
br label %139
139: ; preds = %127
%140 = load i32, i32* %10
%141 = add nsw i32 %140, 1
store i32 %141, i32* %10
br label %78
142: ; preds = %78
br label %143
143: ; preds = %142
%144 = load i32, i32* %9
%145 = add nsw i32 %144, 1
store i32 %145, i32* %9
br label %73
146: ; preds = %73
%147 = load double, double* %15
%148 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), double %147)
%149 = call i64 (...) @clock()
store i64 %149, i64* %7
%150 = load i64, i64* %7
%151 = load i64, i64* %6
%152 = sub nsw i64 %150, %151
%153 = sitofp i64 %152 to double
%154 = load double, double* @CLOCKS_PER_SEC
%155 = fdiv double %153, %154
store double %155, double* %8
%156 = load double, double* %8
%157 = call i32 @printf(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str.3, i64 0, i64 0), double %156)
%158 = load i64, i64* %7
store i64 %158, i64* %6
%159 = load double*, double** %13
%160 = load double*, double** %13
%161 = load double*, double** %14
%162 = call i32 @dgemm_(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i64 0, i64 0), i32* %12, i32* %12, i32* %12, double* %16, double* %159, i32* %12, double* %160, i32* %12, double* %17, double* %161, i32* %12)
%163 = call i64 (...) @clock()
store i64 %163, i64* %7
%164 = load i64, i64* %7
%165 = load i64, i64* %6
%166 = sub nsw i64 %164, %165
%167 = sitofp i64 %166 to double
%168 = load double, double* @CLOCKS_PER_SEC
%169 = fdiv double %167, %168
store double %169, double* %8
%170 = load double, double* %8
%171 = call i32 @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.5, i64 0, i64 0), double %170)
store i32 0, i32* %9
br label %172
172: ; preds = %186, %146
%173 = load i32, i32* %9
%174 = load i32, i32* %12
%175 = load i32, i32* %12
%176 = mul nsw i32 %174, %175
%177 = icmp slt i32 %173, %176
br i1 %177, label %178, label %189
178: ; preds = %172
%179 = load double*, double** %14
%180 = load i32, i32* %9
%181 = sext i32 %180 to i64
%182 = getelementptr inbounds double, double* %179, i64 %181
%183 = load double, double* %182
%184 = load double, double* %15
%185 = fadd double %184, %183
store double %185, double* %15
br label %186
186: ; preds = %178
%187 = load i32, i32* %9
%188 = add nsw i32 %187, 1
store i32 %188, i32* %9
br label %172
189: ; preds = %172
%190 = load double, double* %15
%191 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), double %190)
ret i32 0
}

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