#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;
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
double CLOCKS_PER_SEC;
int /*<<< orphan*/ assignDirichletCondition(int, double, double *, double *,
                                            double *);
double *backSubstitution(int, double *, double *);
scalar_t__ clock();
int /*<<< orphan*/ fclose(int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char *, char *);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/ *, char *, int, double, double,
                           double, double, double, double, double, double,
                           double, double, double, double, double, double);
int /*<<< orphan*/ free(double *);
int /*<<< orphan*/ gaussianElimination(int, double *, double *);
int lineCount(int /*<<< orphan*/ *);
int /*<<< orphan*/ localStiffnessMatrix(double **, double **);
int /*<<< orphan*/ localVector(double **, double, double *);
double omp_get_max_threads();
double omp_get_wtime();
int /*<<< orphan*/ printf(char *, double);
double *readMatrixFile(int /*<<< orphan*/ *, int, int);
double *zeros(int);
double *solvePDE(char fileP[], char fileT[], FILE *result) {
  int vertexSize, globalVertex2, globalVertex, meshSize;
  int tri = 0, i = 0, j = 0;
  double f = -4, g = 1;
  double vertices[3][2] = {{0}};
  double localW[3][3] = {{0}};
  double localB[3] = {1};
  FILE *meshFile = fopen(fileP, "r");
  FILE *vertexFile = fopen(fileT, "r");
  vertexSize = lineCount(vertexFile);
  meshSize = lineCount(meshFile);
  double startIO = omp_get_wtime();
  clock_t startIOCPU = clock();
  double *meshPoints = readMatrixFile(meshFile, lineCount(meshFile), 2);
  double *vertexNumbers = readMatrixFile(vertexFile, lineCount(vertexFile), 3);
  double ioTime = omp_get_wtime() - startIO;
  double ioTimeCPU =
      ((double)(clock() - startIOCPU) / CLOCKS_PER_SEC) / omp_get_max_threads();
  double startZeros = omp_get_wtime();
  clock_t startZerosCPU = clock();
  double *w = zeros(meshSize * meshSize);
  double *b = zeros(meshSize);
  double zerosTime = omp_get_wtime() - startZeros;
  double zerosTimeCPU = ((double)(clock() - startZerosCPU) / CLOCKS_PER_SEC) /
                        omp_get_max_threads();
  double startComputation = omp_get_wtime();
  clock_t startComputationCPU = clock();
#pragma omp parallel for private(tri, i, j, globalVertex, globalVertex2,       \
                                 vertices, localW, localB) schedule(dynamic)
  for (tri = 0; tri < vertexSize; tri++) {
    for (i = 0; i < 3; i++) {
      globalVertex = (int)*(vertexNumbers + tri * 3 + i) - 1;
      vertices[i][0] = *(meshPoints + globalVertex * 2 + 0);
      vertices[i][1] = *(meshPoints + globalVertex * 2 + 1);
    }
    localStiffnessMatrix(vertices, localW);
    localVector(vertices, f, localB);
    for (i = 0; i < 3; i++) {
      globalVertex = (int)*(vertexNumbers + tri * 3 + i) - 1;
#pragma omp critical
      b[globalVertex] += localB[i];
      for (j = 0; j < 3; j++) {
        globalVertex2 = (int)*(vertexNumbers + tri * 3 + j) - 1;
#pragma omp critical
        *(w + globalVertex * meshSize + globalVertex2) += localW[i][j];
      }
    }
  }
  double assemblingTime = omp_get_wtime() - startComputation;
  double assemblingTimeCPU =
      ((double)(clock() - startComputationCPU) / CLOCKS_PER_SEC) /
      omp_get_max_threads();
  double startDirichlet = omp_get_wtime();
  clock_t startDirichletCPU = clock();
  assignDirichletCondition(meshSize, g, meshPoints, w, b);
  double dirichletTime = omp_get_wtime() - startDirichlet;
  double dirichletTimeCPU =
      ((double)(clock() - startDirichletCPU) / CLOCKS_PER_SEC) /
      omp_get_max_threads();
  double startGauss = omp_get_wtime();
  clock_t startGaussCPU = clock();
  gaussianElimination(meshSize, w, b);
  double gaussTime = omp_get_wtime() - startGauss;
  double gaussTimeCPU = ((double)(clock() - startGaussCPU) / CLOCKS_PER_SEC) /
                        omp_get_max_threads();
  double startBack = omp_get_wtime();
  clock_t startBackCPU = clock();
  double *u = backSubstitution(meshSize, w, b);
  double backTime = omp_get_wtime() - startBack;
  double backTimeCPU = ((double)(clock() - startBackCPU) / CLOCKS_PER_SEC) /
                       omp_get_max_threads();
  double computationTime = omp_get_wtime() - startComputation;
  double computationTimeCPU =
      ((double)(clock() - startComputationCPU) / CLOCKS_PER_SEC) /
      omp_get_max_threads();
  printf("Vertex number: %d.\n", meshSize);
  printf("Elapsed time for computation: %lf seconds.\n", computationTime);
  printf("Elapsed time for computation in CPU: %lf seconds.\n",
         computationTimeCPU);
  printf("Elapsed time for IO: %lf seconds.\n", ioTime);
  printf("Elapsed time for IO in CPU: %lf seconds.\n", ioTimeCPU);
  printf("Elapsed time for zeros: %lf seconds.\n", zerosTime);
  printf("Elapsed time for zeros in CPU: %lf seconds.\n", zerosTimeCPU);
  printf("Elapsed time for assembling: %lf seconds.\n", assemblingTime);
  printf("Elapsed time for assembling in CPU: %lf seconds.\n",
         assemblingTimeCPU);
  printf("Elapsed time for dirichlet: %lf seconds.\n", dirichletTime);
  printf("Elapsed time for dirichlet in CPU: %lf seconds.\n", dirichletTimeCPU);
  printf("Elapsed time for gaussian elimination: %lf seconds.\n", gaussTime);
  printf("Elapsed time for gaussian elimination in CPU: %lf seconds.\n",
         gaussTimeCPU);
  printf("Elapsed time for back substitution: %lf seconds.\n", backTime);
  printf("Elapsed time for back substitution in CPU: %lf seconds.\n",
         backTimeCPU);
  fprintf(result,
          "%d; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; "
          "%lf; %lf\n",
          meshSize, computationTime, ioTime, zerosTime, assemblingTime,
          dirichletTime, gaussTime, backTime, computationTimeCPU, ioTimeCPU,
          zerosTimeCPU, assemblingTimeCPU, dirichletTimeCPU, gaussTimeCPU,
          backTimeCPU);
  fclose(meshFile);
  fclose(vertexFile);
  free(meshPoints);
  free(vertexNumbers);
  free(w);
  free(b);
  free(u);
  return u;
}


x86 assembly (clang, -O0):
<solvePDE>:
push   %rbp
mov    %rsp,%rbp
sub    $0x270,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x2c(%rbp)
movl   $0x0,-0x30(%rbp)
movl   $0x0,-0x34(%rbp)
movsd  0xdc4(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xdaf(%rip),%xmm0
movsd  %xmm0,-0x48(%rbp)
lea    -0x80(%rbp),%rdi
xor    %esi,%esi
mov    $0x30,%edx
call   10c0 <memset@plt>
lea    -0xd0(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   10c0 <memset@plt>
mov    0xd90(%rip),%rax
mov    %rax,-0xf0(%rbp)
mov    0xd8a(%rip),%rax
mov    %rax,-0xe8(%rbp)
mov    0xd84(%rip),%rax
mov    %rax,-0xe0(%rbp)
mov    -0x8(%rbp),%rdi
lea    0xd7a(%rip),%rsi
call   1110 <fopen@plt>
mov    %rax,-0xf8(%rbp)
mov    -0x10(%rbp),%rdi
lea    0xd63(%rip),%rsi
call   1110 <fopen@plt>
mov    %rax,-0x100(%rbp)
mov    -0x100(%rbp),%rdi
call   1130 <lineCount@plt>
mov    %eax,-0x1c(%rbp)
mov    -0xf8(%rbp),%rdi
call   1130 <lineCount@plt>
mov    %eax,-0x28(%rbp)
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x108(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x110(%rbp)
mov    -0xf8(%rbp),%rax
mov    %rax,-0x218(%rbp)
mov    -0xf8(%rbp),%rdi
call   1130 <lineCount@plt>
mov    -0x218(%rbp),%rdi
mov    %eax,%esi
mov    $0x2,%edx
call   1040 <readMatrixFile@plt>
mov    %rax,-0x118(%rbp)
mov    -0x100(%rbp),%rax
mov    %rax,-0x210(%rbp)
mov    -0x100(%rbp),%rdi
call   1130 <lineCount@plt>
mov    -0x210(%rbp),%rdi
mov    %eax,%esi
mov    $0x3,%edx
call   1040 <readMatrixFile@plt>
mov    %rax,-0x120(%rbp)
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x108(%rbp),%xmm0
ff
movsd  %xmm0,-0x128(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x110(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2c43(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x208(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x208(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x130(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x138(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x140(%rbp)
mov    -0x28(%rbp),%edi
imul   -0x28(%rbp),%edi
call   1120 <zeros@plt>
mov    %rax,-0x148(%rbp)
mov    -0x28(%rbp),%edi
call   1120 <zeros@plt>
mov    %rax,-0x150(%rbp)
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x138(%rbp),%xmm0
ff
movsd  %xmm0,-0x158(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x140(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2ba9(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x200(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x200(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x160(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x168(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x170(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1654 <solvePDE+0x444>
movl   $0x0,-0x30(%rbp)
cmpl   $0x3,-0x30(%rbp)
jge    152e <solvePDE+0x31e>
mov    -0x120(%rbp),%rax
imul   $0x3,-0x2c(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
cvttsd2si (%rax,%rcx,8),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x118(%rbp),%rax
mov    -0x24(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movslq -0x30(%rbp),%rcx
lea    -0x80(%rbp),%rax
shl    $0x4,%rcx
add    %rcx,%rax
movsd  %xmm0,(%rax)
mov    -0x118(%rbp),%rax
mov    -0x24(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
movsd  0x8(%rax,%rcx,8),%xmm0
movslq -0x30(%rbp),%rcx
lea    -0x80(%rbp),%rax
shl    $0x4,%rcx
add    %rcx,%rax
movsd  %xmm0,0x8(%rax)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    14a0 <solvePDE+0x290>
lea    -0x80(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
call   10a0 <localStiffnessMatrix@plt>
lea    -0x80(%rbp),%rdi
movsd  -0x40(%rbp),%xmm0
lea    -0xf0(%rbp),%rsi
call   1060 <localVector@plt>
movl   $0x0,-0x30(%rbp)
cmpl   $0x3,-0x30(%rbp)
jge    1641 <solvePDE+0x431>
mov    -0x120(%rbp),%rax
imul   $0x3,-0x2c(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
cvttsd2si (%rax,%rcx,8),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
movslq -0x30(%rbp),%rax
movsd  -0xf0(%rbp,%rax,8),%xmm0
ff ff
mov    -0x150(%rbp),%rax
movslq -0x24(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x34(%rbp)
cmpl   $0x3,-0x34(%rbp)
jge    162e <solvePDE+0x41e>
mov    -0x120(%rbp),%rax
imul   $0x3,-0x2c(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
cvttsd2si (%rax,%rcx,8),%eax
sub    $0x1,%eax
mov    %eax,-0x20(%rbp)
movslq -0x30(%rbp),%rcx
lea    -0xd0(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x148(%rbp),%rax
mov    -0x24(%rbp),%ecx
imul   -0x28(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    15b1 <solvePDE+0x3a1>
jmp    1633 <solvePDE+0x423>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    155a <solvePDE+0x34a>
jmp    1646 <solvePDE+0x436>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    148d <solvePDE+0x27d>
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x168(%rbp),%xmm0
ff
movsd  %xmm0,-0x178(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x170(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x2963(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x240(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x240(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x180(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x188(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x190(%rbp)
mov    -0x28(%rbp),%edi
movsd  -0x48(%rbp),%xmm0
mov    -0x118(%rbp),%rsi
mov    -0x148(%rbp),%rdx
mov    -0x150(%rbp),%rcx
call   10f0 <assignDirichletCondition@plt>
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x188(%rbp),%xmm0
ff
movsd  %xmm0,-0x198(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x190(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x28c9(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x238(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x238(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x1a0(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x1a8(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x1b0(%rbp)
mov    -0x28(%rbp),%edi
mov    -0x148(%rbp),%rsi
mov    -0x150(%rbp),%rdx
call   10e0 <gaussianElimination@plt>
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x1a8(%rbp),%xmm0
ff
movsd  %xmm0,-0x1b8(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x1b0(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x283b(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x230(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x230(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x1c0(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,-0x1c8(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
mov    %rax,-0x1d0(%rbp)
mov    -0x28(%rbp),%edi
mov    -0x148(%rbp),%rsi
mov    -0x150(%rbp),%rdx
call   1090 <backSubstitution@plt>
mov    %rax,-0x1d8(%rbp)
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x1c8(%rbp),%xmm0
ff
movsd  %xmm0,-0x1e0(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x1d0(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x27a6(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x228(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x228(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x1e8(%rbp)
ff
mov    $0x0,%al
call   1050 <omp_get_wtime@plt>
subsd  -0x168(%rbp),%xmm0
ff
movsd  %xmm0,-0x1f0(%rbp)
ff
mov    $0x0,%al
call   1070 <clock@plt>
sub    -0x170(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    0x274b(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x220(%rbp)
ff
mov    $0x0,%al
call   1100 <omp_get_max_threads@plt>
movaps %xmm0,%xmm1
movsd  -0x220(%rbp),%xmm0
ff
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x1f8(%rbp)
ff
cvtsi2sdl -0x28(%rbp),%xmm0
lea    0x757(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1f0(%rbp),%xmm0
ff
lea    0x757(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1f8(%rbp),%xmm0
ff
lea    0x76f(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x128(%rbp),%xmm0
ff
lea    0x78e(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x130(%rbp),%xmm0
ff
lea    0x79d(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x158(%rbp),%xmm0
ff
lea    0x7b3(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x160(%rbp),%xmm0
ff
lea    0x7c5(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x178(%rbp),%xmm0
ff
lea    0x7de(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x180(%rbp),%xmm0
ff
lea    0x7f5(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x198(%rbp),%xmm0
ff
lea    0x813(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1a0(%rbp),%xmm0
ff
lea    0x829(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1b8(%rbp),%xmm0
ff
lea    0x846(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1c0(%rbp),%xmm0
ff
lea    0x867(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1e0(%rbp),%xmm0
ff
lea    0x88f(%rip),%rdi
call   10b0 <printf@plt>
movsd  -0x1e8(%rbp),%xmm0
ff
lea    0x8ad(%rip),%rdi
call   10b0 <printf@plt>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%edx
movsd  -0x1f0(%rbp),%xmm0
ff
movsd  -0x128(%rbp),%xmm1
ff
movsd  -0x158(%rbp),%xmm2
ff
movsd  -0x178(%rbp),%xmm3
ff
movsd  -0x198(%rbp),%xmm4
ff
movsd  -0x1b8(%rbp),%xmm5
ff
movsd  -0x1e0(%rbp),%xmm6
ff
movsd  -0x1f8(%rbp),%xmm7
ff
movsd  -0x130(%rbp),%xmm13
ff ff
movsd  -0x160(%rbp),%xmm12
ff ff
movsd  -0x180(%rbp),%xmm11
ff ff
movsd  -0x1a0(%rbp),%xmm10
ff ff
movsd  -0x1c0(%rbp),%xmm9
ff ff
movsd  -0x1e8(%rbp),%xmm8
ff ff
lea    0x85d(%rip),%rsi
movsd  %xmm13,(%rsp)
movsd  %xmm12,0x8(%rsp)
movsd  %xmm11,0x10(%rsp)
movsd  %xmm10,0x18(%rsp)
movsd  %xmm9,0x20(%rsp)
movsd  %xmm8,0x28(%rsp)
call   10d0 <fprintf@plt>
mov    -0xf8(%rbp),%rdi
call   1080 <fclose@plt>
mov    -0x100(%rbp),%rdi
call   1080 <fclose@plt>
mov    -0x118(%rbp),%rdi
call   1030 <free@plt>
mov    -0x120(%rbp),%rdi
call   1030 <free@plt>
mov    -0x148(%rbp),%rdi
call   1030 <free@plt>
mov    -0x150(%rbp),%rdi
call   1030 <free@plt>
mov    -0x1d8(%rbp),%rdi
call   1030 <free@plt>
mov    -0x1d8(%rbp),%rax
add    $0x270,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<solvePDE>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x178,%rsp
mov    %rdx,0xe8(%rsp)
mov    %rsi,%r14
xorps  %xmm0,%xmm0
movaps %xmm0,0x160(%rsp)
movaps %xmm0,0x150(%rsp)
movaps %xmm0,0x140(%rsp)
movaps %xmm0,0x120(%rsp)
movaps %xmm0,0x110(%rsp)
movaps %xmm0,0x100(%rsp)
movaps %xmm0,0xf0(%rsp)
movq   $0x0,0x130(%rsp)
mov    0xdb6(%rip),%rax
mov    %rax,0xc0(%rsp)
movapd 0xd96(%rip),%xmm0
movapd %xmm0,0xb0(%rsp)
lea    0xd9e(%rip),%rbp
mov    %rbp,%rsi
call   1100 <fopen@plt>
mov    %rax,%rbx
mov    %r14,%rdi
mov    %rbp,%rsi
call   1100 <fopen@plt>
mov    %rax,%rbp
mov    %rax,%rdi
call   1120 <lineCount@plt>
mov    %eax,0x38(%rsp)
mov    %rbx,%rdi
call   1120 <lineCount@plt>
mov    %eax,%r15d
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x78(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,%r14
mov    %rbx,%rdi
call   1120 <lineCount@plt>
mov    %rbx,0xe0(%rsp)
mov    %rbx,%rdi
mov    %eax,%esi
mov    $0x2,%edx
call   1040 <readMatrixFile@plt>
mov    %rax,%rbx
mov    %rbp,%rdi
call   1120 <lineCount@plt>
mov    %rbp,0xd8(%rsp)
mov    %rbp,%rdi
mov    %eax,%esi
mov    $0x3,%edx
call   1040 <readMatrixFile@plt>
mov    %rax,%rbp
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x78(%rsp),%xmm0
movsd  %xmm0,0xa8(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    %r14,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x2ca4(%rip),%r13
divsd  0x0(%r13),%xmm0
movsd  %xmm0,0x70(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x70(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x70(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x60(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,%r12
mov    %r15d,%edi
imul   %r15d,%edi
call   1110 <zeros@plt>
mov    %rax,%r14
mov    %r15d,0x78(%rsp)
mov    %r15d,%edi
call   1110 <zeros@plt>
mov    %rax,%r15
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x60(%rsp),%xmm0
movsd  %xmm0,0xa0(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    %r12,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
divsd  0x0(%r13),%xmm0
movsd  %xmm0,0x60(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x60(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x60(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x68(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,0x40(%rsp)
mov    0x38(%rsp),%eax
test   %eax,%eax
jle    1688 <solvePDE+0x488>
mov    %eax,%eax
shl    $0x3,%rax
lea    (%rax,%rax,2),%rax
mov    %rax,0x38(%rsp)
xor    %r13d,%r13d
lea    0x140(%rsp),%r12
nopw   0x0(%rax,%rax,1)
cvttsd2si 0x0(%rbp,%r13,1),%eax
add    %eax,%eax
add    $0xfffffffe,%eax
cltq
movsd  (%rbx,%rax,8),%xmm0
movsd  %xmm0,0x140(%rsp)
movsd  0x8(%rbx,%rax,8),%xmm0
movsd  %xmm0,0x148(%rsp)
cvttsd2si 0x8(%rbp,%r13,1),%eax
lea    -0x2(%rax,%rax,1),%eax
cltq
movsd  (%rbx,%rax,8),%xmm0
movsd  %xmm0,0x150(%rsp)
movsd  0x8(%rbx,%rax,8),%xmm0
movsd  %xmm0,0x158(%rsp)
cvttsd2si 0x10(%rbp,%r13,1),%eax
lea    -0x2(%rax,%rax,1),%eax
cltq
movsd  (%rbx,%rax,8),%xmm0
movsd  %xmm0,0x160(%rsp)
movsd  0x8(%rbx,%rax,8),%xmm0
movsd  %xmm0,0x168(%rsp)
mov    %r12,%rdi
lea    0xf0(%rsp),%rsi
call   10a0 <localStiffnessMatrix@plt>
mov    %r12,%rdi
movsd  0xb36(%rip),%xmm0
lea    0xb0(%rsp),%rsi
call   1060 <localVector@plt>
cvttsd2si 0x0(%rbp,%r13,1),%eax
movsd  0xb0(%rsp),%xmm0
movslq %eax,%rcx
addsd  -0x8(%r15,%rcx,8),%xmm0
add    $0xffffffff,%eax
movsd  %xmm0,-0x8(%r15,%rcx,8)
mov    0x78(%rsp),%edx
imul   %edx,%eax
cltq
lea    (%r14,%rax,8),%rax
cvttsd2si 0x0(%rbp,%r13,1),%ecx
movsd  0xf0(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x8(%rbp,%r13,1),%ecx
movsd  0xf8(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x10(%rbp,%r13,1),%ecx
movsd  0x100(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x8(%rbp,%r13,1),%eax
movsd  0xb8(%rsp),%xmm0
movslq %eax,%rcx
addsd  -0x8(%r15,%rcx,8),%xmm0
add    $0xffffffff,%eax
movsd  %xmm0,-0x8(%r15,%rcx,8)
imul   %edx,%eax
cltq
lea    (%r14,%rax,8),%rax
cvttsd2si 0x0(%rbp,%r13,1),%ecx
movsd  0x108(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x8(%rbp,%r13,1),%ecx
movsd  0x110(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x10(%rbp,%r13,1),%ecx
movsd  0x118(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x10(%rbp,%r13,1),%eax
movsd  0xc0(%rsp),%xmm0
movslq %eax,%rcx
addsd  -0x8(%r15,%rcx,8),%xmm0
add    $0xffffffff,%eax
movsd  %xmm0,-0x8(%r15,%rcx,8)
imul   %edx,%eax
cltq
lea    (%r14,%rax,8),%rax
cvttsd2si 0x0(%rbp,%r13,1),%ecx
movsd  0x120(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x8(%rbp,%r13,1),%ecx
movsd  0x128(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
cvttsd2si 0x10(%rbp,%r13,1),%ecx
movsd  0x130(%rsp),%xmm0
movslq %ecx,%rcx
addsd  -0x8(%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x8(%rax,%rcx,8)
add    $0x18,%r13
cmp    %r13,0x38(%rsp)
jne    1430 <solvePDE+0x230>
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x68(%rsp),%xmm0
movsd  %xmm0,0x98(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    0x40(%rsp),%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x292f(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,0x38(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x38(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x38(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x58(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,%r12
movsd  0x90f(%rip),%xmm0
mov    0x78(%rsp),%r13d
mov    %r13d,%edi
mov    %rbx,%rsi
mov    %r14,%rdx
mov    %r15,%rcx
call   10e0 <assignDirichletCondition@plt>
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x58(%rsp),%xmm0
movsd  %xmm0,0x90(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    %r12,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x28aa(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,0x58(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x58(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x58(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x50(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,%r12
mov    %r13d,%edi
mov    %r14,%rsi
mov    %r15,%rdx
call   10d0 <gaussianElimination@plt>
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x50(%rsp),%xmm0
movsd  %xmm0,0x88(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    %r12,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x2835(%rip),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,0x50(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x50(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x50(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
movsd  %xmm0,0x48(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
mov    %rax,%r12
mov    %r13d,%edi
mov    %r14,%rsi
mov    %r15,%rdx
call   1090 <backSubstitution@plt>
mov    %rax,0xd0(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x48(%rsp),%xmm0
movsd  %xmm0,0x80(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    %r12,%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
mov    0x27b8(%rip),%r12
divsd  (%r12),%xmm0
movsd  %xmm0,0x48(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x48(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x48(%rsp)
xor    %eax,%eax
call   1050 <omp_get_wtime@plt>
subsd  0x68(%rsp),%xmm0
movsd  %xmm0,0x68(%rsp)
xor    %eax,%eax
call   1070 <clock@plt>
sub    0x40(%rsp),%rax
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
divsd  (%r12),%xmm0
movsd  %xmm0,0x40(%rsp)
xor    %eax,%eax
call   10f0 <omp_get_max_threads@plt>
movsd  0x40(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x40(%rsp)
xorps  %xmm0,%xmm0
cvtsi2sd %r13d,%xmm0
lea    0x77e(%rip),%rdi
call   10b0 <printf@plt>
lea    0x786(%rip),%rdi
movsd  0x68(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x7a0(%rip),%rdi
movsd  0x40(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x7c1(%rip),%rdi
movsd  0xa8(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x7cf(%rip),%rdi
movsd  0x70(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x7e7(%rip),%rdi
movsd  0xa0(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x7f8(%rip),%rdi
movsd  0x60(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x813(%rip),%rdi
movsd  0x98(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x829(%rip),%rdi
movsd  0x38(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x849(%rip),%rdi
movsd  0x90(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x85e(%rip),%rdi
movsd  0x58(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x87d(%rip),%rdi
movsd  0x88(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x89d(%rip),%rdi
movsd  0x50(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x8c7(%rip),%rdi
movsd  0x80(%rsp),%xmm0
call   10b0 <printf@plt>
lea    0x8e4(%rip),%rdi
movsd  0x48(%rsp),%xmm0
call   10b0 <printf@plt>
movsd  0x48(%rsp),%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0x50(%rsp),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0x58(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
movsd  0x38(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0x60(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x70(%rsp),%xmm0
movsd  %xmm0,(%rsp)
lea    0x8c4(%rip),%rsi
mov    0xe8(%rsp),%rdi
mov    %r13d,%edx
movsd  0x68(%rsp),%xmm0
movsd  0xa8(%rsp),%xmm1
movsd  0xa0(%rsp),%xmm2
movsd  0x98(%rsp),%xmm3
movsd  0x90(%rsp),%xmm4
movsd  0x88(%rsp),%xmm5
movsd  0x80(%rsp),%xmm6
movsd  0x40(%rsp),%xmm7
call   10c0 <fprintf@plt>
mov    0xe0(%rsp),%rdi
call   1080 <fclose@plt>
mov    0xd8(%rsp),%rdi
call   1080 <fclose@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %rbp,%rdi
call   1030 <free@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r15,%rdi
call   1030 <free@plt>
mov    0xd0(%rsp),%rbx
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %rbx,%rax
add    $0x178,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.solvePDE.localB = [3 x double] [double 1.000000e+00, double 0.000000e+00, double 0.000000e+00]
@.str = [2 x i8] c"r\00"
@CLOCKS_PER_SEC = global double 0.000000e+00
@.str.1 = [20 x i8] c"Vertex number: %d.\0A\00"
@.str.2 = [44 x i8] c"Elapsed time for computation: %lf seconds.\0A\00"
@.str.3 = [51 x i8] c"Elapsed time for computation in CPU: %lf seconds.\0A\00"
@.str.4 = [35 x i8] c"Elapsed time for IO: %lf seconds.\0A\00"
@.str.5 = [42 x i8] c"Elapsed time for IO in CPU: %lf seconds.\0A\00"
@.str.6 = [38 x i8] c"Elapsed time for zeros: %lf seconds.\0A\00"
@.str.7 = [45 x i8] c"Elapsed time for zeros in CPU: %lf seconds.\0A\00"
@.str.8 = [43 x i8] c"Elapsed time for assembling: %lf seconds.\0A\00"
@.str.9 = [50 x i8] c"Elapsed time for assembling in CPU: %lf seconds.\0A\00"
@.str.10 = [42 x i8] c"Elapsed time for dirichlet: %lf seconds.\0A\00"
@.str.11 = [49 x i8] c"Elapsed time for dirichlet in CPU: %lf seconds.\0A\00"
@.str.12 = [53 x i8] c"Elapsed time for gaussian elimination: %lf seconds.\0A\00"
@.str.13 = [60 x i8] c"Elapsed time for gaussian elimination in CPU: %lf seconds.\0A\00"
@.str.14 = [50 x i8] c"Elapsed time for back substitution: %lf seconds.\0A\00"
@.str.15 = [57 x i8] c"Elapsed time for back substitution in CPU: %lf seconds.\0A\00"
@.str.16 = [74 x i8] c"%d; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf\0A\00"
define double* @solvePDE(i8* %0, i8* %1, i32* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca double
%15 = alloca double
%16 = alloca [3 x [2 x double]]
%17 = alloca [3 x [3 x double]]
%18 = alloca [3 x double]
%19 = alloca i32*
%20 = alloca i32*
%21 = alloca double
%22 = alloca i64
%23 = alloca double*
%24 = alloca double*
%25 = alloca double
%26 = alloca double
%27 = alloca double
%28 = alloca i64
%29 = alloca double*
%30 = alloca double*
%31 = alloca double
%32 = alloca double
%33 = alloca double
%34 = alloca i64
%35 = alloca double
%36 = alloca double
%37 = alloca double
%38 = alloca i64
%39 = alloca double
%40 = alloca double
%41 = alloca double
%42 = alloca i64
%43 = alloca double
%44 = alloca double
%45 = alloca double
%46 = alloca i64
%47 = alloca double*
%48 = alloca double
%49 = alloca double
%50 = alloca double
%51 = alloca double
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32* %2, i32** %6
store i32 0, i32* %11
store i32 0, i32* %12
store i32 0, i32* %13
store double -4.000000e+00, double* %14
store double 1.000000e+00, double* %15
%52 = bitcast [3 x [2 x double]]* %16 to i8*
%53 = bitcast [3 x [3 x double]]* %17 to i8*
%54 = bitcast [3 x double]* %18 to i8*
%55 = load i8*, i8** %4
%56 = call i32* @fopen(i8* %55, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %56, i32** %19
%57 = load i8*, i8** %5
%58 = call i32* @fopen(i8* %57, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %58, i32** %20
%59 = load i32*, i32** %20
%60 = call i32 @lineCount(i32* %59)
store i32 %60, i32* %7
%61 = load i32*, i32** %19
%62 = call i32 @lineCount(i32* %61)
store i32 %62, i32* %10
%63 = call double (...) @omp_get_wtime()
store double %63, double* %21
%64 = call i64 (...) @clock()
store i64 %64, i64* %22
%65 = load i32*, i32** %19
%66 = load i32*, i32** %19
%67 = call i32 @lineCount(i32* %66)
%68 = call double* @readMatrixFile(i32* %65, i32 %67, i32 2)
store double* %68, double** %23
%69 = load i32*, i32** %20
%70 = load i32*, i32** %20
%71 = call i32 @lineCount(i32* %70)
%72 = call double* @readMatrixFile(i32* %69, i32 %71, i32 3)
store double* %72, double** %24
%73 = call double (...) @omp_get_wtime()
%74 = load double, double* %21
%75 = fsub double %73, %74
store double %75, double* %25
%76 = call i64 (...) @clock()
%77 = load i64, i64* %22
%78 = sub nsw i64 %76, %77
%79 = sitofp i64 %78 to double
%80 = load double, double* @CLOCKS_PER_SEC
%81 = fdiv double %79, %80
%82 = call double (...) @omp_get_max_threads()
%83 = fdiv double %81, %82
store double %83, double* %26
%84 = call double (...) @omp_get_wtime()
store double %84, double* %27
%85 = call i64 (...) @clock()
store i64 %85, i64* %28
%86 = load i32, i32* %10
%87 = load i32, i32* %10
%88 = mul nsw i32 %86, %87
%89 = call double* @zeros(i32 %88)
store double* %89, double** %29
%90 = load i32, i32* %10
%91 = call double* @zeros(i32 %90)
store double* %91, double** %30
%92 = call double (...) @omp_get_wtime()
%93 = load double, double* %27
%94 = fsub double %92, %93
store double %94, double* %31
%95 = call i64 (...) @clock()
%96 = load i64, i64* %28
%97 = sub nsw i64 %95, %96
%98 = sitofp i64 %97 to double
%99 = load double, double* @CLOCKS_PER_SEC
%100 = fdiv double %98, %99
%101 = call double (...) @omp_get_max_threads()
%102 = fdiv double %100, %101
store double %102, double* %32
%103 = call double (...) @omp_get_wtime()
store double %103, double* %33
%104 = call i64 (...) @clock()
store i64 %104, i64* %34
store i32 0, i32* %11
br label %105
105: ; preds = %227, %3
%106 = load i32, i32* %11
%107 = load i32, i32* %7
%108 = icmp slt i32 %106, %107
br i1 %108, label %109, label %230
109: ; preds = %105
store i32 0, i32* %12
br label %110
110: ; preds = %147, %109
%111 = load i32, i32* %12
%112 = icmp slt i32 %111, 3
br i1 %112, label %113, label %150
113: ; preds = %110
%114 = load double*, double** %24
%115 = load i32, i32* %11
%116 = mul nsw i32 %115, 3
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds double, double* %114, i64 %117
%119 = load i32, i32* %12
%120 = sext i32 %119 to i64
%121 = getelementptr inbounds double, double* %118, i64 %120
%122 = load double, double* %121
%123 = fptosi double %122 to i32
%124 = sub nsw i32 %123, 1
store i32 %124, i32* %9
%125 = load double*, double** %23
%126 = load i32, i32* %9
%127 = mul nsw i32 %126, 2
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds double, double* %125, i64 %128
%130 = getelementptr inbounds double, double* %129, i64 0
%131 = load double, double* %130
%132 = load i32, i32* %12
%133 = sext i32 %132 to i64
%134 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %16, i64 0, i64 %133
%135 = getelementptr inbounds [2 x double], [2 x double]* %134, i64 0, i64 0
store double %131, double* %135
%136 = load double*, double** %23
%137 = load i32, i32* %9
%138 = mul nsw i32 %137, 2
%139 = sext i32 %138 to i64
%140 = getelementptr inbounds double, double* %136, i64 %139
%141 = getelementptr inbounds double, double* %140, i64 1
%142 = load double, double* %141
%143 = load i32, i32* %12
%144 = sext i32 %143 to i64
%145 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %16, i64 0, i64 %144
%146 = getelementptr inbounds [2 x double], [2 x double]* %145, i64 0, i64 1
store double %142, double* %146
br label %147
147: ; preds = %113
%148 = load i32, i32* %12
%149 = add nsw i32 %148, 1
store i32 %149, i32* %12
br label %110
150: ; preds = %110
%151 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %16, i64 0, i64 0
%152 = bitcast [2 x double]* %151 to double**
%153 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %17, i64 0, i64 0
%154 = bitcast [3 x double]* %153 to double**
%155 = call i32 @localStiffnessMatrix(double** %152, double** %154)
%156 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %16, i64 0, i64 0
%157 = bitcast [2 x double]* %156 to double**
%158 = load double, double* %14
%159 = getelementptr inbounds [3 x double], [3 x double]* %18, i64 0, i64 0
%160 = call i32 @localVector(double** %157, double %158, double* %159)
store i32 0, i32* %12
br label %161
161: ; preds = %223, %150
%162 = load i32, i32* %12
%163 = icmp slt i32 %162, 3
br i1 %163, label %164, label %226
164: ; preds = %161
%165 = load double*, double** %24
%166 = load i32, i32* %11
%167 = mul nsw i32 %166, 3
%168 = sext i32 %167 to i64
%169 = getelementptr inbounds double, double* %165, i64 %168
%170 = load i32, i32* %12
%171 = sext i32 %170 to i64
%172 = getelementptr inbounds double, double* %169, i64 %171
%173 = load double, double* %172
%174 = fptosi double %173 to i32
%175 = sub nsw i32 %174, 1
store i32 %175, i32* %9
%176 = load i32, i32* %12
%177 = sext i32 %176 to i64
%178 = getelementptr inbounds [3 x double], [3 x double]* %18, i64 0, i64 %177
%179 = load double, double* %178
%180 = load double*, double** %30
%181 = load i32, i32* %9
%182 = sext i32 %181 to i64
%183 = getelementptr inbounds double, double* %180, i64 %182
%184 = load double, double* %183
%185 = fadd double %184, %179
store double %185, double* %183
store i32 0, i32* %13
br label %186
186: ; preds = %219, %164
%187 = load i32, i32* %13
%188 = icmp slt i32 %187, 3
br i1 %188, label %189, label %222
189: ; preds = %186
%190 = load double*, double** %24
%191 = load i32, i32* %11
%192 = mul nsw i32 %191, 3
%193 = sext i32 %192 to i64
%194 = getelementptr inbounds double, double* %190, i64 %193
%195 = load i32, i32* %13
%196 = sext i32 %195 to i64
%197 = getelementptr inbounds double, double* %194, i64 %196
%198 = load double, double* %197
%199 = fptosi double %198 to i32
%200 = sub nsw i32 %199, 1
store i32 %200, i32* %8
%201 = load i32, i32* %12
%202 = sext i32 %201 to i64
%203 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %17, i64 0, i64 %202
%204 = load i32, i32* %13
%205 = sext i32 %204 to i64
%206 = getelementptr inbounds [3 x double], [3 x double]* %203, i64 0, i64 %205
%207 = load double, double* %206
%208 = load double*, double** %29
%209 = load i32, i32* %9
%210 = load i32, i32* %10
%211 = mul nsw i32 %209, %210
%212 = sext i32 %211 to i64
%213 = getelementptr inbounds double, double* %208, i64 %212
%214 = load i32, i32* %8
%215 = sext i32 %214 to i64
%216 = getelementptr inbounds double, double* %213, i64 %215
%217 = load double, double* %216
%218 = fadd double %217, %207
store double %218, double* %216
br label %219
219: ; preds = %189
%220 = load i32, i32* %13
%221 = add nsw i32 %220, 1
store i32 %221, i32* %13
br label %186
222: ; preds = %186
br label %223
223: ; preds = %222
%224 = load i32, i32* %12
%225 = add nsw i32 %224, 1
store i32 %225, i32* %12
br label %161
226: ; preds = %161
br label %227
227: ; preds = %226
%228 = load i32, i32* %11
%229 = add nsw i32 %228, 1
store i32 %229, i32* %11
br label %105
230: ; preds = %105
%231 = call double (...) @omp_get_wtime()
%232 = load double, double* %33
%233 = fsub double %231, %232
store double %233, double* %35
%234 = call i64 (...) @clock()
%235 = load i64, i64* %34
%236 = sub nsw i64 %234, %235
%237 = sitofp i64 %236 to double
%238 = load double, double* @CLOCKS_PER_SEC
%239 = fdiv double %237, %238
%240 = call double (...) @omp_get_max_threads()
%241 = fdiv double %239, %240
store double %241, double* %36
%242 = call double (...) @omp_get_wtime()
store double %242, double* %37
%243 = call i64 (...) @clock()
store i64 %243, i64* %38
%244 = load i32, i32* %10
%245 = load double, double* %15
%246 = load double*, double** %23
%247 = load double*, double** %29
%248 = load double*, double** %30
%249 = call i32 @assignDirichletCondition(i32 %244, double %245, double* %246, double* %247, double* %248)
%250 = call double (...) @omp_get_wtime()
%251 = load double, double* %37
%252 = fsub double %250, %251
store double %252, double* %39
%253 = call i64 (...) @clock()
%254 = load i64, i64* %38
%255 = sub nsw i64 %253, %254
%256 = sitofp i64 %255 to double
%257 = load double, double* @CLOCKS_PER_SEC
%258 = fdiv double %256, %257
%259 = call double (...) @omp_get_max_threads()
%260 = fdiv double %258, %259
store double %260, double* %40
%261 = call double (...) @omp_get_wtime()
store double %261, double* %41
%262 = call i64 (...) @clock()
store i64 %262, i64* %42
%263 = load i32, i32* %10
%264 = load double*, double** %29
%265 = load double*, double** %30
%266 = call i32 @gaussianElimination(i32 %263, double* %264, double* %265)
%267 = call double (...) @omp_get_wtime()
%268 = load double, double* %41
%269 = fsub double %267, %268
store double %269, double* %43
%270 = call i64 (...) @clock()
%271 = load i64, i64* %42
%272 = sub nsw i64 %270, %271
%273 = sitofp i64 %272 to double
%274 = load double, double* @CLOCKS_PER_SEC
%275 = fdiv double %273, %274
%276 = call double (...) @omp_get_max_threads()
%277 = fdiv double %275, %276
store double %277, double* %44
%278 = call double (...) @omp_get_wtime()
store double %278, double* %45
%279 = call i64 (...) @clock()
store i64 %279, i64* %46
%280 = load i32, i32* %10
%281 = load double*, double** %29
%282 = load double*, double** %30
%283 = call double* @backSubstitution(i32 %280, double* %281, double* %282)
store double* %283, double** %47
%284 = call double (...) @omp_get_wtime()
%285 = load double, double* %45
%286 = fsub double %284, %285
store double %286, double* %48
%287 = call i64 (...) @clock()
%288 = load i64, i64* %46
%289 = sub nsw i64 %287, %288
%290 = sitofp i64 %289 to double
%291 = load double, double* @CLOCKS_PER_SEC
%292 = fdiv double %290, %291
%293 = call double (...) @omp_get_max_threads()
%294 = fdiv double %292, %293
store double %294, double* %49
%295 = call double (...) @omp_get_wtime()
%296 = load double, double* %33
%297 = fsub double %295, %296
store double %297, double* %50
%298 = call i64 (...) @clock()
%299 = load i64, i64* %34
%300 = sub nsw i64 %298, %299
%301 = sitofp i64 %300 to double
%302 = load double, double* @CLOCKS_PER_SEC
%303 = fdiv double %301, %302
%304 = call double (...) @omp_get_max_threads()
%305 = fdiv double %303, %304
store double %305, double* %51
%306 = load i32, i32* %10
%307 = sitofp i32 %306 to double
%308 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i64 0, i64 0), double %307)
%309 = load double, double* %50
%310 = call i32 @printf(i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.2, i64 0, i64 0), double %309)
%311 = load double, double* %51
%312 = call i32 @printf(i8* getelementptr inbounds ([51 x i8], [51 x i8]* @.str.3, i64 0, i64 0), double %311)
%313 = load double, double* %25
%314 = call i32 @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.4, i64 0, i64 0), double %313)
%315 = load double, double* %26
%316 = call i32 @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.5, i64 0, i64 0), double %315)
%317 = load double, double* %31
%318 = call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.6, i64 0, i64 0), double %317)
%319 = load double, double* %32
%320 = call i32 @printf(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.7, i64 0, i64 0), double %319)
%321 = load double, double* %35
%322 = call i32 @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.8, i64 0, i64 0), double %321)
%323 = load double, double* %36
%324 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.9, i64 0, i64 0), double %323)
%325 = load double, double* %39
%326 = call i32 @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.10, i64 0, i64 0), double %325)
%327 = load double, double* %40
%328 = call i32 @printf(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.11, i64 0, i64 0), double %327)
%329 = load double, double* %43
%330 = call i32 @printf(i8* getelementptr inbounds ([53 x i8], [53 x i8]* @.str.12, i64 0, i64 0), double %329)
%331 = load double, double* %44
%332 = call i32 @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.13, i64 0, i64 0), double %331)
%333 = load double, double* %48
%334 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.14, i64 0, i64 0), double %333)
%335 = load double, double* %49
%336 = call i32 @printf(i8* getelementptr inbounds ([57 x i8], [57 x i8]* @.str.15, i64 0, i64 0), double %335)
%337 = load i32*, i32** %6
%338 = load i32, i32* %10
%339 = load double, double* %50
%340 = load double, double* %25
%341 = load double, double* %31
%342 = load double, double* %35
%343 = load double, double* %39
%344 = load double, double* %43
%345 = load double, double* %48
%346 = load double, double* %51
%347 = load double, double* %26
%348 = load double, double* %32
%349 = load double, double* %36
%350 = load double, double* %40
%351 = load double, double* %44
%352 = load double, double* %49
%353 = call i32 @fprintf(i32* %337, i8* getelementptr inbounds ([74 x i8], [74 x i8]* @.str.16, i64 0, i64 0), i32 %338, double %339, double %340, double %341, double %342, double %343, double %344, double %345, double %346, double %347, double %348, double %349, double %350, double %351, double %352)
%354 = load i32*, i32** %19
%355 = call i32 @fclose(i32* %354)
%356 = load i32*, i32** %20
%357 = call i32 @fclose(i32* %356)
%358 = load double*, double** %23
%359 = call i32 @free(double* %358)
%360 = load double*, double** %24
%361 = call i32 @free(double* %360)
%362 = load double*, double** %29
%363 = call i32 @free(double* %362)
%364 = load double*, double** %30
%365 = call i32 @free(double* %364)
%366 = load double*, double** %47
%367 = call i32 @free(double* %366)
%368 = load double*, double** %47
ret double* %368
}

LLVM IR (-O2):
@__const.solvePDE.localB = [3 x double] [double 1.000000e+00, double 0.000000e+00, double 0.000000e+00]
@.str = [2 x i8] c"r\00"
@CLOCKS_PER_SEC = global double 0.000000e+00
@.str.1 = [20 x i8] c"Vertex number: %d.\0A\00"
@.str.2 = [44 x i8] c"Elapsed time for computation: %lf seconds.\0A\00"
@.str.3 = [51 x i8] c"Elapsed time for computation in CPU: %lf seconds.\0A\00"
@.str.4 = [35 x i8] c"Elapsed time for IO: %lf seconds.\0A\00"
@.str.5 = [42 x i8] c"Elapsed time for IO in CPU: %lf seconds.\0A\00"
@.str.6 = [38 x i8] c"Elapsed time for zeros: %lf seconds.\0A\00"
@.str.7 = [45 x i8] c"Elapsed time for zeros in CPU: %lf seconds.\0A\00"
@.str.8 = [43 x i8] c"Elapsed time for assembling: %lf seconds.\0A\00"
@.str.9 = [50 x i8] c"Elapsed time for assembling in CPU: %lf seconds.\0A\00"
@.str.10 = [42 x i8] c"Elapsed time for dirichlet: %lf seconds.\0A\00"
@.str.11 = [49 x i8] c"Elapsed time for dirichlet in CPU: %lf seconds.\0A\00"
@.str.12 = [53 x i8] c"Elapsed time for gaussian elimination: %lf seconds.\0A\00"
@.str.13 = [60 x i8] c"Elapsed time for gaussian elimination in CPU: %lf seconds.\0A\00"
@.str.14 = [50 x i8] c"Elapsed time for back substitution: %lf seconds.\0A\00"
@.str.15 = [57 x i8] c"Elapsed time for back substitution in CPU: %lf seconds.\0A\00"
@.str.16 = [74 x i8] c"%d; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf; %lf\0A\00"
define double* @solvePDE(i8* nocapture %0, i8* nocapture %1, i32* nocapture %2) {
%4 = alloca [3 x [2 x double]]
%5 = alloca [3 x [3 x double]]
%6 = alloca [3 x double]
%7 = bitcast [3 x [2 x double]]* %4 to i8*
%8 = bitcast [3 x [3 x double]]* %5 to i8*
%9 = bitcast [3 x double]* %6 to i8*
%10 = tail call i32* @fopen(i8* %0, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%11 = tail call i32* @fopen(i8* %1, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%12 = tail call i32 @lineCount(i32* %11)
%13 = tail call i32 @lineCount(i32* %10)
%14 = tail call double (...) @omp_get_wtime()
%15 = tail call i64 (...) @clock()
%16 = tail call i32 @lineCount(i32* %10)
%17 = tail call double* @readMatrixFile(i32* %10, i32 %16, i32 2)
%18 = tail call i32 @lineCount(i32* %11)
%19 = tail call double* @readMatrixFile(i32* %11, i32 %18, i32 3)
%20 = tail call double (...) @omp_get_wtime()
%21 = fsub double %20, %14
%22 = tail call i64 (...) @clock()
%23 = sub nsw i64 %22, %15
%24 = sitofp i64 %23 to double
%25 = load double, double* @CLOCKS_PER_SEC
%26 = fdiv double %24, %25
%27 = tail call double (...) @omp_get_max_threads()
%28 = fdiv double %26, %27
%29 = tail call double (...) @omp_get_wtime()
%30 = tail call i64 (...) @clock()
%31 = mul nsw i32 %13, %13
%32 = tail call double* @zeros(i32 %31)
%33 = tail call double* @zeros(i32 %13)
%34 = tail call double (...) @omp_get_wtime()
%35 = fsub double %34, %29
%36 = tail call i64 (...) @clock()
%37 = sub nsw i64 %36, %30
%38 = sitofp i64 %37 to double
%39 = load double, double* @CLOCKS_PER_SEC
%40 = fdiv double %38, %39
%41 = tail call double (...) @omp_get_max_threads()
%42 = fdiv double %40, %41
%43 = tail call double (...) @omp_get_wtime()
%44 = tail call i64 (...) @clock()
%45 = icmp sgt i32 %12, 0
br i1 %45, label %46, label %210
46: ; preds = %3
%47 = bitcast [3 x [2 x double]]* %4 to double**
%48 = bitcast [3 x [3 x double]]* %5 to double**
%49 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 0
%50 = zext i32 %12 to i64
%51 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 0, i64 0
%52 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 0, i64 1
%53 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 1, i64 0
%54 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 1, i64 1
%55 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 2, i64 0
%56 = getelementptr inbounds [3 x [2 x double]], [3 x [2 x double]]* %4, i64 0, i64 2, i64 1
%57 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 0, i64 0
%58 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 0, i64 1
%59 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 0, i64 2
%60 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 1
%61 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 1, i64 0
%62 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 1, i64 1
%63 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 1, i64 2
%64 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 2
%65 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 2, i64 0
%66 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 2, i64 1
%67 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 2, i64 2
br label %68
68: ; preds = %46, %68
%69 = phi i64 [ 0, %46 ], [ %208, %68 ]
%70 = mul nuw nsw i64 %69, 3
%71 = getelementptr inbounds double, double* %19, i64 %70
%72 = load double, double* %71
%73 = fptosi double %72 to i32
%74 = shl i32 %73, 1
%75 = add i32 %74, -2
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds double, double* %17, i64 %76
%78 = load double, double* %77
store double %78, double* %51
%79 = getelementptr inbounds double, double* %77, i64 1
%80 = load double, double* %79
store double %80, double* %52
%81 = getelementptr inbounds double, double* %71, i64 1
%82 = load double, double* %81
%83 = fptosi double %82 to i32
%84 = shl i32 %83, 1
%85 = add i32 %84, -2
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds double, double* %17, i64 %86
%88 = load double, double* %87
store double %88, double* %53
%89 = getelementptr inbounds double, double* %87, i64 1
%90 = load double, double* %89
store double %90, double* %54
%91 = getelementptr inbounds double, double* %71, i64 2
%92 = load double, double* %91
%93 = fptosi double %92 to i32
%94 = shl i32 %93, 1
%95 = add i32 %94, -2
%96 = sext i32 %95 to i64
%97 = getelementptr inbounds double, double* %17, i64 %96
%98 = load double, double* %97
store double %98, double* %55
%99 = getelementptr inbounds double, double* %97, i64 1
%100 = load double, double* %99
store double %100, double* %56
%101 = call i32 @localStiffnessMatrix(double** %47, double** %48)
%102 = call i32 @localVector(double** %47, double -4.000000e+00, double* %49)
%103 = load double, double* %71
%104 = fptosi double %103 to i32
%105 = add nsw i32 %104, -1
%106 = load double, double* %49
%107 = sext i32 %105 to i64
%108 = getelementptr inbounds double, double* %33, i64 %107
%109 = load double, double* %108
%110 = fadd double %106, %109
store double %110, double* %108
%111 = mul nsw i32 %105, %13
%112 = sext i32 %111 to i64
%113 = getelementptr inbounds double, double* %32, i64 %112
%114 = load double, double* %71
%115 = fptosi double %114 to i32
%116 = add nsw i32 %115, -1
%117 = load double, double* %57
%118 = sext i32 %116 to i64
%119 = getelementptr inbounds double, double* %113, i64 %118
%120 = load double, double* %119
%121 = fadd double %117, %120
store double %121, double* %119
%122 = load double, double* %81
%123 = fptosi double %122 to i32
%124 = add nsw i32 %123, -1
%125 = load double, double* %58
%126 = sext i32 %124 to i64
%127 = getelementptr inbounds double, double* %113, i64 %126
%128 = load double, double* %127
%129 = fadd double %125, %128
store double %129, double* %127
%130 = load double, double* %91
%131 = fptosi double %130 to i32
%132 = add nsw i32 %131, -1
%133 = load double, double* %59
%134 = sext i32 %132 to i64
%135 = getelementptr inbounds double, double* %113, i64 %134
%136 = load double, double* %135
%137 = fadd double %133, %136
store double %137, double* %135
%138 = load double, double* %81
%139 = fptosi double %138 to i32
%140 = add nsw i32 %139, -1
%141 = load double, double* %60
%142 = sext i32 %140 to i64
%143 = getelementptr inbounds double, double* %33, i64 %142
%144 = load double, double* %143
%145 = fadd double %141, %144
store double %145, double* %143
%146 = mul nsw i32 %140, %13
%147 = sext i32 %146 to i64
%148 = getelementptr inbounds double, double* %32, i64 %147
%149 = load double, double* %71
%150 = fptosi double %149 to i32
%151 = add nsw i32 %150, -1
%152 = load double, double* %61
%153 = sext i32 %151 to i64
%154 = getelementptr inbounds double, double* %148, i64 %153
%155 = load double, double* %154
%156 = fadd double %152, %155
store double %156, double* %154
%157 = load double, double* %81
%158 = fptosi double %157 to i32
%159 = add nsw i32 %158, -1
%160 = load double, double* %62
%161 = sext i32 %159 to i64
%162 = getelementptr inbounds double, double* %148, i64 %161
%163 = load double, double* %162
%164 = fadd double %160, %163
store double %164, double* %162
%165 = load double, double* %91
%166 = fptosi double %165 to i32
%167 = add nsw i32 %166, -1
%168 = load double, double* %63
%169 = sext i32 %167 to i64
%170 = getelementptr inbounds double, double* %148, i64 %169
%171 = load double, double* %170
%172 = fadd double %168, %171
store double %172, double* %170
%173 = load double, double* %91
%174 = fptosi double %173 to i32
%175 = add nsw i32 %174, -1
%176 = load double, double* %64
%177 = sext i32 %175 to i64
%178 = getelementptr inbounds double, double* %33, i64 %177
%179 = load double, double* %178
%180 = fadd double %176, %179
store double %180, double* %178
%181 = mul nsw i32 %175, %13
%182 = sext i32 %181 to i64
%183 = getelementptr inbounds double, double* %32, i64 %182
%184 = load double, double* %71
%185 = fptosi double %184 to i32
%186 = add nsw i32 %185, -1
%187 = load double, double* %65
%188 = sext i32 %186 to i64
%189 = getelementptr inbounds double, double* %183, i64 %188
%190 = load double, double* %189
%191 = fadd double %187, %190
store double %191, double* %189
%192 = load double, double* %81
%193 = fptosi double %192 to i32
%194 = add nsw i32 %193, -1
%195 = load double, double* %66
%196 = sext i32 %194 to i64
%197 = getelementptr inbounds double, double* %183, i64 %196
%198 = load double, double* %197
%199 = fadd double %195, %198
store double %199, double* %197
%200 = load double, double* %91
%201 = fptosi double %200 to i32
%202 = add nsw i32 %201, -1
%203 = load double, double* %67
%204 = sext i32 %202 to i64
%205 = getelementptr inbounds double, double* %183, i64 %204
%206 = load double, double* %205
%207 = fadd double %203, %206
store double %207, double* %205
%208 = add nuw nsw i64 %69, 1
%209 = icmp eq i64 %208, %50
br i1 %209, label %210, label %68
210: ; preds = %68, %3
%211 = call double (...) @omp_get_wtime()
%212 = fsub double %211, %43
%213 = call i64 (...) @clock()
%214 = sub nsw i64 %213, %44
%215 = sitofp i64 %214 to double
%216 = load double, double* @CLOCKS_PER_SEC
%217 = fdiv double %215, %216
%218 = call double (...) @omp_get_max_threads()
%219 = fdiv double %217, %218
%220 = call double (...) @omp_get_wtime()
%221 = call i64 (...) @clock()
%222 = call i32 @assignDirichletCondition(i32 %13, double 1.000000e+00, double* %17, double* %32, double* %33)
%223 = call double (...) @omp_get_wtime()
%224 = fsub double %223, %220
%225 = call i64 (...) @clock()
%226 = sub nsw i64 %225, %221
%227 = sitofp i64 %226 to double
%228 = load double, double* @CLOCKS_PER_SEC
%229 = fdiv double %227, %228
%230 = call double (...) @omp_get_max_threads()
%231 = fdiv double %229, %230
%232 = call double (...) @omp_get_wtime()
%233 = call i64 (...) @clock()
%234 = call i32 @gaussianElimination(i32 %13, double* %32, double* %33)
%235 = call double (...) @omp_get_wtime()
%236 = fsub double %235, %232
%237 = call i64 (...) @clock()
%238 = sub nsw i64 %237, %233
%239 = sitofp i64 %238 to double
%240 = load double, double* @CLOCKS_PER_SEC
%241 = fdiv double %239, %240
%242 = call double (...) @omp_get_max_threads()
%243 = fdiv double %241, %242
%244 = call double (...) @omp_get_wtime()
%245 = call i64 (...) @clock()
%246 = call double* @backSubstitution(i32 %13, double* %32, double* %33)
%247 = call double (...) @omp_get_wtime()
%248 = fsub double %247, %244
%249 = call i64 (...) @clock()
%250 = sub nsw i64 %249, %245
%251 = sitofp i64 %250 to double
%252 = load double, double* @CLOCKS_PER_SEC
%253 = fdiv double %251, %252
%254 = call double (...) @omp_get_max_threads()
%255 = fdiv double %253, %254
%256 = call double (...) @omp_get_wtime()
%257 = fsub double %256, %43
%258 = call i64 (...) @clock()
%259 = sub nsw i64 %258, %44
%260 = sitofp i64 %259 to double
%261 = load double, double* @CLOCKS_PER_SEC
%262 = fdiv double %260, %261
%263 = call double (...) @omp_get_max_threads()
%264 = fdiv double %262, %263
%265 = sitofp i32 %13 to double
%266 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i64 0, i64 0), double %265)
%267 = call i32 @printf(i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.2, i64 0, i64 0), double %257)
%268 = call i32 @printf(i8* getelementptr inbounds ([51 x i8], [51 x i8]* @.str.3, i64 0, i64 0), double %264)
%269 = call i32 @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.4, i64 0, i64 0), double %21)
%270 = call i32 @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.5, i64 0, i64 0), double %28)
%271 = call i32 @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.6, i64 0, i64 0), double %35)
%272 = call i32 @printf(i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.7, i64 0, i64 0), double %42)
%273 = call i32 @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.8, i64 0, i64 0), double %212)
%274 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.9, i64 0, i64 0), double %219)
%275 = call i32 @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.10, i64 0, i64 0), double %224)
%276 = call i32 @printf(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.11, i64 0, i64 0), double %231)
%277 = call i32 @printf(i8* getelementptr inbounds ([53 x i8], [53 x i8]* @.str.12, i64 0, i64 0), double %236)
%278 = call i32 @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.13, i64 0, i64 0), double %243)
%279 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.14, i64 0, i64 0), double %248)
%280 = call i32 @printf(i8* getelementptr inbounds ([57 x i8], [57 x i8]* @.str.15, i64 0, i64 0), double %255)
%281 = call i32 @fprintf(i32* %2, i8* getelementptr inbounds ([74 x i8], [74 x i8]* @.str.16, i64 0, i64 0), i32 %13, double %257, double %21, double %35, double %212, double %224, double %236, double %248, double %264, double %28, double %42, double %219, double %231, double %243, double %255)
%282 = call i32 @fclose(i32* %10)
%283 = call i32 @fclose(i32* %11)
%284 = call i32 @free(double* %17)
%285 = call i32 @free(double* %19)
%286 = call i32 @free(double* %32)
%287 = call i32 @free(double* %33)
%288 = call i32 @free(double* %246)
ret double* %246
}