#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 /*<<< orphan*/);
long atoi(char *);
long atol(char *);
int /*<<< orphan*/ exit(int);
int loopParCollapse(long, double **, double *, long, long, long);
int loopParNested(long, double **, double *, long, long, long);
scalar_t__ malloc(int);
int /*<<< orphan*/ printf(char *, ...);
int main(int argc, char *argv[]) {
  long int numThreads, matRows, matCols, vectorSize, i, j;
  double **matrix, *vector;
  if (argc != 5) {
    printf("\t\t Very Few Arguments\n ");
    printf("\t\t Syntax : exec <Threads> <NoOfRows> <NoofColumns> "
           "<vector-size>\n");
    exit(-1);
  }
  numThreads = atoi(argv[1]);
  if ((numThreads != 1) && (numThreads != 2) && (numThreads != 4) &&
      (numThreads != 8) && (numThreads != 16)) {
    printf("\n Number of threads should be 1,2,4,8 or 16 for the execution of "
           "program. \n\n");
    exit(-1);
  }
  matRows = atol(argv[2]);
  matCols = atol(argv[3]);
  vectorSize = atol(argv[4]);
  if (matRows <= 0 || matCols <= 0 || vectorSize <= 0) {
    printf("\n\t\t The Matrix and Vectorsize should be of positive sign\n");
    exit(-1);
  }
  if (matCols != vectorSize) {
    printf("\n\t\t Matrix Vector computation cannot be possible \n");
    exit(-1);
  }
  assert((matrix = (double **)malloc(sizeof(double) * matRows)) != NULL);
  for (i = 0; i < matRows; i++) {
    assert((matrix[i] = (double *)malloc(sizeof(double) * matCols)) != NULL);
    for (j = 0; j < matCols; j++)
      matrix[i][j] = i + j;
  }
  assert((vector = (double *)malloc(sizeof(double) * vectorSize)) != NULL);
  for (i = 0; i < vectorSize; i++)
    vector[i] = i;
  printf("\n\t\t Matrix Size       : %ld * %ld ", matRows, matCols);
  printf("\n\t\t Vector Size       : %ld      ", vectorSize);
  printf("\n\t\t Number of threads : %ld      ", numThreads);
  if ((loopParCollapse(numThreads, matrix, vector, matRows, matCols,
                       vectorSize)) == 1) {
    printf("\n\t Matrix Vector Multiplication Collapse clause is failed \n");
    exit(-1);
  }
  if ((loopParNested(numThreads, matrix, vector, matRows, matCols,
                     vectorSize)) == 1) {
    printf("\n\t Matrix Vector Multiplication Netsed Approach is failed \n");
    exit(-1);
  }
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0x5,-0x8(%rbp)
je     11c6 <main+0x46>
lea    0xe59(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xe63(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1080 <atoi@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x1,-0x18(%rbp)
je     1226 <main+0xa6>
cmpq   $0x2,-0x18(%rbp)
je     1226 <main+0xa6>
cmpq   $0x4,-0x18(%rbp)
je     1226 <main+0xa6>
cmpq   $0x8,-0x18(%rbp)
je     1226 <main+0xa6>
cmpq   $0x10,-0x18(%rbp)
je     1226 <main+0xa6>
lea    0xe46(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
call   1070 <atol@plt>
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    0x18(%rax),%rdi
call   1070 <atol@plt>
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    0x20(%rax),%rdi
call   1070 <atol@plt>
mov    %rax,-0x30(%rbp)
cmpq   $0x0,-0x20(%rbp)
jle    127a <main+0xfa>
cmpq   $0x0,-0x28(%rbp)
jle    127a <main+0xfa>
cmpq   $0x0,-0x30(%rbp)
jg     1292 <main+0x112>
lea    0xe27(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x28(%rbp),%rax
cmp    -0x30(%rbp),%rax
je     12b8 <main+0x138>
lea    0xe3b(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x20(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1060 <malloc@plt>
mov    %rax,-0x48(%rbp)
cmp    $0x0,%rax
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x20(%rbp),%rax
jge    137d <main+0x1fd>
mov    -0x28(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1060 <malloc@plt>
mov    -0x48(%rbp),%rcx
mov    -0x38(%rbp),%rdx
mov    %rax,(%rcx,%rdx,8)
cmp    $0x0,%rax
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x28(%rbp),%rax
jge    1367 <main+0x1e7>
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
cvtsi2sd %rax,%xmm0
mov    -0x48(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x40(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1326 <main+0x1a6>
jmp    136c <main+0x1ec>
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    12e4 <main+0x164>
mov    -0x30(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1060 <malloc@plt>
mov    %rax,-0x50(%rbp)
cmp    $0x0,%rax
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x30(%rbp),%rax
jge    13db <main+0x25b>
cvtsi2sdq -0x38(%rbp),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    13a9 <main+0x229>
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
lea    0xd2b(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x30(%rbp),%rsi
lea    0xd3c(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x18(%rbp),%rsi
lea    0xd4c(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x18(%rbp),%rdi
mov    -0x48(%rbp),%rsi
mov    -0x50(%rbp),%rdx
mov    -0x20(%rbp),%rcx
mov    -0x28(%rbp),%r8
mov    -0x30(%rbp),%r9
call   1040 <loopParCollapse@plt>
cmp    $0x1,%eax
jne    1453 <main+0x2d3>
lea    0xd3a(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x18(%rbp),%rdi
mov    -0x48(%rbp),%rsi
mov    -0x50(%rbp),%rdx
mov    -0x20(%rbp),%rcx
mov    -0x28(%rbp),%r8
mov    -0x30(%rbp),%r9
call   10a0 <loopParNested@plt>
cmp    $0x1,%eax
jne    1491 <main+0x311>
lea    0xd38(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0xffffffff,%edi
call   1090 <exit@plt>
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
cmp    $0x5,%edi
jne    1656 <main+0x4c6>
mov    %rsi,%rbp
mov    0x8(%rsi),%rdi
call   1090 <atoi@plt>
cmp    $0x10,%rax
ja     167f <main+0x4ef>
mov    %rax,%r14
mov    $0x10116,%eax
bt     %r14,%rax
jae    167f <main+0x4ef>
mov    0x10(%rbp),%rdi
call   1080 <atol@plt>
mov    %rax,%r15
mov    0x18(%rbp),%rdi
call   1080 <atol@plt>
mov    %rax,%rbx
mov    0x20(%rbp),%rdi
call   1080 <atol@plt>
test   %r15,%r15
jle    166d <main+0x4dd>
test   %rbx,%rbx
jle    166d <main+0x4dd>
test   %rax,%rax
jle    166d <main+0x4dd>
mov    %r14,0x18(%rsp)
cmp    %rax,%rbx
jne    1676 <main+0x4e6>
mov    %r15,%r14
lea    0x0(,%r15,8),%edi
call   1070 <malloc@plt>
mov    %rax,%r12
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1060 <assert@plt>
lea    0x0(,%rbx,8),%r13d
lea    -0x4(%rbx),%rcx
mov    %rcx,0x10(%rsp)
shr    $0x2,%rcx
add    $0x1,%rcx
mov    %rbx,%rbp
and    $0xfffffffffffffffc,%rbp
mov    %rcx,%rax
mov    %rcx,0x8(%rsp)
and    $0xfffffffffffffffe,%rcx
mov    %rcx,0x20(%rsp)
xor    %r15d,%r15d
jmp    127d <main+0xed>
add    $0x1,%r15
cmp    %r14,%r15
je     148f <main+0x2ff>
mov    %r13d,%edi
call   1070 <malloc@plt>
mov    %rax,(%r12,%r15,8)
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1060 <assert@plt>
mov    (%r12,%r15,8),%rax
cmp    $0x4,%rbx
jae    12b0 <main+0x120>
xor    %ecx,%ecx
jmp    1470 <main+0x2e0>
nopl   0x0(%rax,%rax,1)
movq   %r15,%xmm0
pshufd $0x44,%xmm0,%xmm0
cmpq   $0x4,0x10(%rsp)
jae    12e0 <main+0x150>
xor    %ecx,%ecx
movdqa 0xd34(%rip),%xmm1
jmp    13ea <main+0x25a>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    0x2(%r15),%rcx
movq   %rcx,%xmm1
pshufd $0x44,%xmm1,%xmm2
mov    0x20(%rsp),%rdx
xor    %ecx,%ecx
movdqa 0xd03(%rip),%xmm1
movdqa 0xd0a(%rip),%xmm8
movdqa 0xd12(%rip),%xmm7
xchg   %ax,%ax
movdqa %xmm1,%xmm3
paddq  %xmm0,%xmm3
movdqa %xmm2,%xmm4
movq   %xmm3,%rsi
xorps  %xmm5,%xmm5
cvtsi2sd %rsi,%xmm5
pshufd $0xee,%xmm3,%xmm3
movq   %xmm3,%rsi
xorps  %xmm3,%xmm3
cvtsi2sd %rsi,%xmm3
paddq  %xmm1,%xmm4
movq   %xmm4,%rsi
xorps  %xmm6,%xmm6
cvtsi2sd %rsi,%xmm6
pshufd $0xee,%xmm4,%xmm4
movq   %xmm4,%rsi
xorps  %xmm4,%xmm4
cvtsi2sd %rsi,%xmm4
unpcklpd %xmm3,%xmm5
unpcklpd %xmm4,%xmm6
movupd %xmm5,(%rax,%rcx,8)
movupd %xmm6,0x10(%rax,%rcx,8)
movdqa %xmm1,%xmm3
paddq  %xmm8,%xmm3
movdqa %xmm2,%xmm4
paddq  %xmm3,%xmm4
paddq  %xmm0,%xmm3
movq   %xmm3,%rsi
xorps  %xmm5,%xmm5
cvtsi2sd %rsi,%xmm5
pshufd $0xee,%xmm3,%xmm3
movq   %xmm3,%rsi
xorps  %xmm3,%xmm3
cvtsi2sd %rsi,%xmm3
unpcklpd %xmm3,%xmm5
movq   %xmm4,%rsi
xorps  %xmm3,%xmm3
cvtsi2sd %rsi,%xmm3
pshufd $0xee,%xmm4,%xmm4
movq   %xmm4,%rsi
xorps  %xmm4,%xmm4
cvtsi2sd %rsi,%xmm4
unpcklpd %xmm4,%xmm3
movupd %xmm5,0x20(%rax,%rcx,8)
movupd %xmm3,0x30(%rax,%rcx,8)
add    $0x8,%rcx
paddq  %xmm7,%xmm1
add    $0xfffffffffffffffe,%rdx
jne    1310 <main+0x180>
testb  $0x1,0x8(%rsp)
je     1458 <main+0x2c8>
paddq  %xmm1,%xmm0
lea    0x2(%r15),%rdx
movq   %rdx,%xmm2
pshufd $0x44,%xmm2,%xmm2
movq   %xmm0,%rdx
xorps  %xmm3,%xmm3
cvtsi2sd %rdx,%xmm3
pshufd $0xee,%xmm0,%xmm0
movq   %xmm0,%rdx
xorps  %xmm0,%xmm0
cvtsi2sd %rdx,%xmm0
paddq  %xmm1,%xmm2
movq   %xmm2,%rdx
xorps  %xmm1,%xmm1
cvtsi2sd %rdx,%xmm1
pshufd $0xee,%xmm2,%xmm2
movq   %xmm2,%rdx
xorps  %xmm2,%xmm2
cvtsi2sd %rdx,%xmm2
unpcklpd %xmm0,%xmm3
unpcklpd %xmm2,%xmm1
movupd %xmm3,(%rax,%rcx,8)
movupd %xmm1,0x10(%rax,%rcx,8)
mov    %rbp,%rcx
cmp    %rbp,%rbx
je     1270 <main+0xe0>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    (%r15,%rcx,1),%rdx
xorps  %xmm0,%xmm0
cvtsi2sd %rdx,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
add    $0x1,%rcx
cmp    %rcx,%rbx
jne    1470 <main+0x2e0>
jmp    1270 <main+0xe0>
mov    %r13d,%edi
call   1070 <malloc@plt>
mov    %rax,%r13
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1060 <assert@plt>
test   %rbx,%rbx
jle    16ad <main+0x51d>
cmp    $0x4,%rbx
jae    14be <main+0x32e>
xor    %ecx,%ecx
jmp    1695 <main+0x505>
cmpq   $0x4,0x10(%rsp)
jae    14d5 <main+0x345>
movdqa 0xb32(%rip),%xmm0
xor    %eax,%eax
jmp    15e2 <main+0x452>
movabs $0x7ffffffffffffffe,%rdx
ff ff 7f
and    0x8(%rsp),%rdx
movdqa 0xb14(%rip),%xmm0
xor    %eax,%eax
movdqa 0xb3a(%rip),%xmm1
movdqa 0xb42(%rip),%xmm2
movdqa 0xb0a(%rip),%xmm6
movdqa 0xb12(%rip),%xmm7
xchg   %ax,%ax
movdqa %xmm0,%xmm3
paddq  %xmm1,%xmm3
movq   %xmm0,%rcx
xorps  %xmm4,%xmm4
cvtsi2sd %rcx,%xmm4
pshufd $0xee,%xmm0,%xmm5
movq   %xmm5,%rcx
xorps  %xmm5,%xmm5
cvtsi2sd %rcx,%xmm5
unpcklpd %xmm5,%xmm4
movq   %xmm3,%rcx
xorps  %xmm5,%xmm5
cvtsi2sd %rcx,%xmm5
pshufd $0xee,%xmm3,%xmm3
movq   %xmm3,%rcx
xorps  %xmm3,%xmm3
cvtsi2sd %rcx,%xmm3
unpcklpd %xmm3,%xmm5
movupd %xmm4,0x0(%r13,%rax,8)
movupd %xmm5,0x10(%r13,%rax,8)
movdqa %xmm0,%xmm3
paddq  %xmm6,%xmm3
movdqa %xmm0,%xmm4
paddq  %xmm2,%xmm4
movq   %xmm3,%rcx
xorps  %xmm5,%xmm5
cvtsi2sd %rcx,%xmm5
pshufd $0xee,%xmm3,%xmm3
movq   %xmm3,%rcx
xorps  %xmm3,%xmm3
cvtsi2sd %rcx,%xmm3
unpcklpd %xmm3,%xmm5
movq   %xmm4,%rcx
xorps  %xmm3,%xmm3
cvtsi2sd %rcx,%xmm3
pshufd $0xee,%xmm4,%xmm4
movq   %xmm4,%rcx
xorps  %xmm4,%xmm4
cvtsi2sd %rcx,%xmm4
unpcklpd %xmm4,%xmm3
movupd %xmm5,0x20(%r13,%rax,8)
movupd %xmm3,0x30(%r13,%rax,8)
add    $0x8,%rax
paddq  %xmm7,%xmm0
add    $0xfffffffffffffffe,%rdx
jne    1510 <main+0x380>
mov    %rbx,%rcx
and    $0xfffffffffffffffc,%rcx
testb  $0x1,0x8(%rsp)
je     16a8 <main+0x518>
movdqa 0xa34(%rip),%xmm1
movq   %xmm0,%rdx
xorps  %xmm2,%xmm2
cvtsi2sd %rdx,%xmm2
pshufd $0xee,%xmm0,%xmm3
movq   %xmm3,%rdx
xorps  %xmm3,%xmm3
cvtsi2sd %rdx,%xmm3
paddq  %xmm0,%xmm1
movq   %xmm1,%rdx
xorps  %xmm0,%xmm0
cvtsi2sd %rdx,%xmm0
pshufd $0xee,%xmm1,%xmm1
movq   %xmm1,%rdx
xorps  %xmm1,%xmm1
cvtsi2sd %rdx,%xmm1
unpcklpd %xmm3,%xmm2
unpcklpd %xmm1,%xmm0
movupd %xmm2,0x0(%r13,%rax,8)
movupd %xmm0,0x10(%r13,%rax,8)
jmp    16a8 <main+0x518>
lea    0x9f3(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xb91(%rip),%rdi
jmp    1686 <main+0x4f6>
lea    0xb03(%rip),%rdi
jmp    1686 <main+0x4f6>
lea    0xac8(%rip),%rdi
jmp    1686 <main+0x4f6>
lea    0xb2a(%rip),%rdi
call   1030 <puts@plt>
mov    $0xffffffff,%edi
call   10a0 <exit@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rcx,%xmm0
movsd  %xmm0,0x0(%r13,%rcx,8)
add    $0x1,%rcx
cmp    %rcx,%rbx
jne    1695 <main+0x505>
lea    0x9b4(%rip),%rdi
mov    %r14,%rsi
mov    %rbx,%rdx
xor    %eax,%eax
call   1040 <printf@plt>
lea    0x9c3(%rip),%rdi
mov    %rbx,%rsi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0x9d4(%rip),%rdi
mov    0x18(%rsp),%rbp
mov    %rbp,%rsi
xor    %eax,%eax
call   1040 <printf@plt>
mov    %rbp,%rdi
mov    %r12,%rsi
mov    %r13,%rdx
mov    %r14,%rcx
mov    %rbx,%r8
mov    %rbx,%r9
call   1050 <loopParCollapse@plt>
cmp    $0x1,%eax
je     1731 <main+0x5a1>
mov    %rbp,%rdi
mov    %r12,%rsi
mov    %r13,%rdx
mov    %r14,%rcx
mov    %rbx,%r8
mov    %rbx,%r9
call   10b0 <loopParNested@plt>
cmp    $0x1,%eax
je     173d <main+0x5ad>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0x9d2(%rip),%rdi
jmp    1686 <main+0x4f6>
lea    0x98b(%rip),%rdi
jmp    1686 <main+0x4f6>

LLVM IR (-O0):
@.str = [24 x i8] c"\09\09 Very Few Arguments\0A \00"
@.str.1 = [67 x i8] c"\09\09 Syntax : exec <Threads> <NoOfRows> <NoofColumns> <vector-size>\0A\00"
@.str.2 = [77 x i8] c"\0A Number of threads should be 1,2,4,8 or 16 for the execution of program. \0A\0A\00"
@.str.3 = [58 x i8] c"\0A\09\09 The Matrix and Vectorsize should be of positive sign\0A\00"
@.str.4 = [51 x i8] c"\0A\09\09 Matrix Vector computation cannot be possible \0A\00"
@.str.5 = [35 x i8] c"\0A\09\09 Matrix Size : %ld * %ld \00"
@.str.6 = [34 x i8] c"\0A\09\09 Vector Size : %ld \00"
@.str.7 = [34 x i8] c"\0A\09\09 Number of threads : %ld \00"
@.str.8 = [60 x i8] c"\0A\09 Matrix Vector Multiplication Collapse clause is failed \0A\00"
@.str.9 = [60 x i8] c"\0A\09 Matrix Vector Multiplication Netsed Approach is failed \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 i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca double**
%13 = alloca double*
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%14 = load i32, i32* %4
%15 = icmp ne i32 %14, 5
br i1 %15, label %16, label %20
16: ; preds = %2
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0))
%18 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([67 x i8], [67 x i8]* @.str.1, i64 0, i64 0))
%19 = call i32 @exit(i32 -1)
unreachable
20: ; preds = %2
%21 = load i8**, i8*** %5
%22 = getelementptr inbounds i8*, i8** %21, i64 1
%23 = load i8*, i8** %22
%24 = call i64 @atoi(i8* %23)
store i64 %24, i64* %6
%25 = load i64, i64* %6
%26 = icmp ne i64 %25, 1
br i1 %26, label %27, label %42
27: ; preds = %20
%28 = load i64, i64* %6
%29 = icmp ne i64 %28, 2
br i1 %29, label %30, label %42
30: ; preds = %27
%31 = load i64, i64* %6
%32 = icmp ne i64 %31, 4
br i1 %32, label %33, label %42
33: ; preds = %30
%34 = load i64, i64* %6
%35 = icmp ne i64 %34, 8
br i1 %35, label %36, label %42
36: ; preds = %33
%37 = load i64, i64* %6
%38 = icmp ne i64 %37, 16
br i1 %38, label %39, label %42
39: ; preds = %36
%40 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([77 x i8], [77 x i8]* @.str.2, i64 0, i64 0))
%41 = call i32 @exit(i32 -1)
unreachable
42: ; preds = %36, %33, %30, %27, %20
%43 = load i8**, i8*** %5
%44 = getelementptr inbounds i8*, i8** %43, i64 2
%45 = load i8*, i8** %44
%46 = call i64 @atol(i8* %45)
store i64 %46, i64* %7
%47 = load i8**, i8*** %5
%48 = getelementptr inbounds i8*, i8** %47, i64 3
%49 = load i8*, i8** %48
%50 = call i64 @atol(i8* %49)
store i64 %50, i64* %8
%51 = load i8**, i8*** %5
%52 = getelementptr inbounds i8*, i8** %51, i64 4
%53 = load i8*, i8** %52
%54 = call i64 @atol(i8* %53)
store i64 %54, i64* %9
%55 = load i64, i64* %7
%56 = icmp sle i64 %55, 0
br i1 %56, label %63, label %57
57: ; preds = %42
%58 = load i64, i64* %8
%59 = icmp sle i64 %58, 0
br i1 %59, label %63, label %60
60: ; preds = %57
%61 = load i64, i64* %9
%62 = icmp sle i64 %61, 0
br i1 %62, label %63, label %66
63: ; preds = %60, %57, %42
%64 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([58 x i8], [58 x i8]* @.str.3, i64 0, i64 0))
%65 = call i32 @exit(i32 -1)
unreachable
66: ; preds = %60
%67 = load i64, i64* %8
%68 = load i64, i64* %9
%69 = icmp ne i64 %67, %68
br i1 %69, label %70, label %73
70: ; preds = %66
%71 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([51 x i8], [51 x i8]* @.str.4, i64 0, i64 0))
%72 = call i32 @exit(i32 -1)
unreachable
73: ; preds = %66
%74 = load i64, i64* %7
%75 = mul i64 8, %74
%76 = trunc i64 %75 to i32
%77 = call i64 @malloc(i32 %76)
%78 = inttoptr i64 %77 to double**
store double** %78, double*** %12
%79 = icmp ne double** %78, null
%80 = zext i1 %79 to i32
%81 = call i32 @assert(i32 %80)
store i64 0, i64* %10
br label %82
82: ; preds = %117, %73
%83 = load i64, i64* %10
%84 = load i64, i64* %7
%85 = icmp slt i64 %83, %84
br i1 %85, label %86, label %120
86: ; preds = %82
%87 = load i64, i64* %8
%88 = mul i64 8, %87
%89 = trunc i64 %88 to i32
%90 = call i64 @malloc(i32 %89)
%91 = inttoptr i64 %90 to double*
%92 = load double**, double*** %12
%93 = load i64, i64* %10
%94 = getelementptr inbounds double*, double** %92, i64 %93
store double* %91, double** %94
%95 = icmp ne double* %91, null
%96 = zext i1 %95 to i32
%97 = call i32 @assert(i32 %96)
store i64 0, i64* %11
br label %98
98: ; preds = %113, %86
%99 = load i64, i64* %11
%100 = load i64, i64* %8
%101 = icmp slt i64 %99, %100
br i1 %101, label %102, label %116
102: ; preds = %98
%103 = load i64, i64* %10
%104 = load i64, i64* %11
%105 = add nsw i64 %103, %104
%106 = sitofp i64 %105 to double
%107 = load double**, double*** %12
%108 = load i64, i64* %10
%109 = getelementptr inbounds double*, double** %107, i64 %108
%110 = load double*, double** %109
%111 = load i64, i64* %11
%112 = getelementptr inbounds double, double* %110, i64 %111
store double %106, double* %112
br label %113
113: ; preds = %102
%114 = load i64, i64* %11
%115 = add nsw i64 %114, 1
store i64 %115, i64* %11
br label %98
116: ; preds = %98
br label %117
117: ; preds = %116
%118 = load i64, i64* %10
%119 = add nsw i64 %118, 1
store i64 %119, i64* %10
br label %82
120: ; preds = %82
%121 = load i64, i64* %9
%122 = mul i64 8, %121
%123 = trunc i64 %122 to i32
%124 = call i64 @malloc(i32 %123)
%125 = inttoptr i64 %124 to double*
store double* %125, double** %13
%126 = icmp ne double* %125, null
%127 = zext i1 %126 to i32
%128 = call i32 @assert(i32 %127)
store i64 0, i64* %10
br label %129
129: ; preds = %139, %120
%130 = load i64, i64* %10
%131 = load i64, i64* %9
%132 = icmp slt i64 %130, %131
br i1 %132, label %133, label %142
133: ; preds = %129
%134 = load i64, i64* %10
%135 = sitofp i64 %134 to double
%136 = load double*, double** %13
%137 = load i64, i64* %10
%138 = getelementptr inbounds double, double* %136, i64 %137
store double %135, double* %138
br label %139
139: ; preds = %133
%140 = load i64, i64* %10
%141 = add nsw i64 %140, 1
store i64 %141, i64* %10
br label %129
142: ; preds = %129
%143 = load i64, i64* %7
%144 = load i64, i64* %8
%145 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.5, i64 0, i64 0), i64 %143, i64 %144)
%146 = load i64, i64* %9
%147 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.6, i64 0, i64 0), i64 %146)
%148 = load i64, i64* %6
%149 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.7, i64 0, i64 0), i64 %148)
%150 = load i64, i64* %6
%151 = load double**, double*** %12
%152 = load double*, double** %13
%153 = load i64, i64* %7
%154 = load i64, i64* %8
%155 = load i64, i64* %9
%156 = call i32 @loopParCollapse(i64 %150, double** %151, double* %152, i64 %153, i64 %154, i64 %155)
%157 = icmp eq i32 %156, 1
br i1 %157, label %158, label %161
158: ; preds = %142
%159 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.8, i64 0, i64 0))
%160 = call i32 @exit(i32 -1)
unreachable
161: ; preds = %142
%162 = load i64, i64* %6
%163 = load double**, double*** %12
%164 = load double*, double** %13
%165 = load i64, i64* %7
%166 = load i64, i64* %8
%167 = load i64, i64* %9
%168 = call i32 @loopParNested(i64 %162, double** %163, double* %164, i64 %165, i64 %166, i64 %167)
%169 = icmp eq i32 %168, 1
br i1 %169, label %170, label %173
170: ; preds = %161
%171 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.9, i64 0, i64 0))
%172 = call i32 @exit(i32 -1)
unreachable
173: ; preds = %161
%174 = load i32, i32* %3
ret i32 %174
}

LLVM IR (-O2):
@.str = [24 x i8] c"\09\09 Very Few Arguments\0A \00"
@.str.5 = [35 x i8] c"\0A\09\09 Matrix Size : %ld * %ld \00"
@.str.6 = [34 x i8] c"\0A\09\09 Vector Size : %ld \00"
@.str.7 = [34 x i8] c"\0A\09\09 Number of threads : %ld \00"
@str = [59 x i8] c"\0A\09 Matrix Vector Multiplication Netsed Approach is failed \00"
@str.10 = [59 x i8] c"\0A\09 Matrix Vector Multiplication Collapse clause is failed \00"
@str.11 = [50 x i8] c"\0A\09\09 Matrix Vector computation cannot be possible \00"
@str.12 = [57 x i8] c"\0A\09\09 The Matrix and Vectorsize should be of positive sign\00"
@str.13 = [76 x i8] c"\0A Number of threads should be 1,2,4,8 or 16 for the execution of program. \0A\00"
@str.14 = [66 x i8] c"\09\09 Syntax : exec <Threads> <NoOfRows> <NoofColumns> <vector-size>\00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = icmp eq i32 %0, 5
br i1 %3, label %8, label %4
4: ; preds = %2
%5 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0))
%6 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([66 x i8], [66 x i8]* @str.14, i64 0, i64 0))
%7 = tail call i32 @exit(i32 -1)
unreachable
8: ; preds = %2
%9 = getelementptr inbounds i8*, i8** %1, i64 1
%10 = load i8*, i8** %9
%11 = tail call i64 @atoi(i8* %10)
switch i64 %11, label %12 [
i64 16, label %15
i64 8, label %15
i64 4, label %15
i64 2, label %15
i64 1, label %15
]
12: ; preds = %8
%13 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([76 x i8], [76 x i8]* @str.13, i64 0, i64 0))
%14 = tail call i32 @exit(i32 -1)
unreachable
15: ; preds = %8, %8, %8, %8, %8
%16 = getelementptr inbounds i8*, i8** %1, i64 2
%17 = load i8*, i8** %16
%18 = tail call i64 @atol(i8* %17)
%19 = getelementptr inbounds i8*, i8** %1, i64 3
%20 = load i8*, i8** %19
%21 = tail call i64 @atol(i8* %20)
%22 = getelementptr inbounds i8*, i8** %1, i64 4
%23 = load i8*, i8** %22
%24 = tail call i64 @atol(i8* %23)
%25 = icmp slt i64 %18, 1
%26 = icmp slt i64 %21, 1
%27 = select i1 %25, i1 true, i1 %26
%28 = icmp slt i64 %24, 1
%29 = select i1 %27, i1 true, i1 %28
br i1 %29, label %30, label %33
30: ; preds = %15
%31 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([57 x i8], [57 x i8]* @str.12, i64 0, i64 0))
%32 = tail call i32 @exit(i32 -1)
unreachable
33: ; preds = %15
%34 = icmp eq i64 %21, %24
br i1 %34, label %38, label %35
35: ; preds = %33
%36 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([50 x i8], [50 x i8]* @str.11, i64 0, i64 0))
%37 = tail call i32 @exit(i32 -1)
unreachable
38: ; preds = %33
%39 = trunc i64 %18 to i32
%40 = shl i32 %39, 3
%41 = tail call i64 @malloc(i32 %40)
%42 = inttoptr i64 %41 to double**
%43 = icmp ne i64 %41, 0
%44 = zext i1 %43 to i32
%45 = tail call i32 @assert(i32 %44)
%46 = trunc i64 %21 to i32
%47 = shl i32 %46, 3
%48 = add i64 %21, -4
%49 = lshr i64 %48, 2
%50 = add nuw nsw i64 %49, 1
%51 = icmp ult i64 %21, 4
%52 = and i64 %21, -4
%53 = and i64 %50, 1
%54 = icmp ult i64 %48, 4
%55 = and i64 %50, 9223372036854775806
%56 = icmp eq i64 %53, 0
%57 = icmp eq i64 %21, %52
br label %58
58: ; preds = %38, %128
%59 = phi i64 [ 0, %38 ], [ %129, %128 ]
%60 = tail call i64 @malloc(i32 %47)
%61 = inttoptr i64 %60 to double*
%62 = getelementptr inbounds double*, double** %42, i64 %59
store double* %61, double** %62
%63 = icmp ne i64 %60, 0
%64 = zext i1 %63 to i32
%65 = tail call i32 @assert(i32 %64)
%66 = load double*, double** %62
br i1 %51, label %119, label %67
67: ; preds = %58
%68 = insertelement <2 x i64> poison, i64 %59, i64 0
%69 = shufflevector <2 x i64> %68, <2 x i64> poison, <2 x i32> zeroinitializer
br i1 %54, label %103, label %70
70: ; preds = %67
%71 = add nuw i64 %59, 2
%72 = insertelement <2 x i64> poison, i64 %71, i64 0
%73 = shufflevector <2 x i64> %72, <2 x i64> poison, <2 x i32> zeroinitializer
%74 = add nuw i64 %59, 2
%75 = insertelement <2 x i64> poison, i64 %74, i64 0
%76 = shufflevector <2 x i64> %75, <2 x i64> poison, <2 x i32> zeroinitializer
br label %77
77: ; preds = %77, %70
%78 = phi i64 [ 0, %70 ], [ %99, %77 ]
%79 = phi <2 x i64> [ <i64 0, i64 1>, %70 ], [ %100, %77 ]
%80 = phi i64 [ 0, %70 ], [ %101, %77 ]
%81 = add nuw nsw <2 x i64> %79, %69
%82 = add <2 x i64> %73, %79
%83 = sitofp <2 x i64> %81 to <2 x double>
%84 = sitofp <2 x i64> %82 to <2 x double>
%85 = getelementptr inbounds double, double* %66, i64 %78
%86 = bitcast double* %85 to <2 x double>*
store <2 x double> %83, <2 x double>* %86
%87 = getelementptr inbounds double, double* %85, i64 2
%88 = bitcast double* %87 to <2 x double>*
store <2 x double> %84, <2 x double>* %88
%89 = or i64 %78, 4
%90 = add <2 x i64> %79, <i64 4, i64 4>
%91 = add nuw nsw <2 x i64> %90, %69
%92 = add <2 x i64> %76, %90
%93 = sitofp <2 x i64> %91 to <2 x double>
%94 = sitofp <2 x i64> %92 to <2 x double>
%95 = getelementptr inbounds double, double* %66, i64 %89
%96 = bitcast double* %95 to <2 x double>*
store <2 x double> %93, <2 x double>* %96
%97 = getelementptr inbounds double, double* %95, i64 2
%98 = bitcast double* %97 to <2 x double>*
store <2 x double> %94, <2 x double>* %98
%99 = add nuw i64 %78, 8
%100 = add <2 x i64> %79, <i64 8, i64 8>
%101 = add i64 %80, 2
%102 = icmp eq i64 %101, %55
br i1 %102, label %103, label %77
103: ; preds = %77, %67
%104 = phi i64 [ 0, %67 ], [ %99, %77 ]
%105 = phi <2 x i64> [ <i64 0, i64 1>, %67 ], [ %100, %77 ]
br i1 %56, label %118, label %106
106: ; preds = %103
%107 = add nuw nsw <2 x i64> %105, %69
%108 = add nuw i64 %59, 2
%109 = insertelement <2 x i64> poison, i64 %108, i64 0
%110 = shufflevector <2 x i64> %109, <2 x i64> poison, <2 x i32> zeroinitializer
%111 = add <2 x i64> %110, %105
%112 = sitofp <2 x i64> %107 to <2 x double>
%113 = sitofp <2 x i64> %111 to <2 x double>
%114 = getelementptr inbounds double, double* %66, i64 %104
%115 = bitcast double* %114 to <2 x double>*
store <2 x double> %112, <2 x double>* %115
%116 = getelementptr inbounds double, double* %114, i64 2
%117 = bitcast double* %116 to <2 x double>*
store <2 x double> %113, <2 x double>* %117
br label %118
118: ; preds = %103, %106
br i1 %57, label %128, label %119
119: ; preds = %58, %118
%120 = phi i64 [ 0, %58 ], [ %52, %118 ]
br label %121
121: ; preds = %119, %121
%122 = phi i64 [ %126, %121 ], [ %120, %119 ]
%123 = add nuw nsw i64 %122, %59
%124 = sitofp i64 %123 to double
%125 = getelementptr inbounds double, double* %66, i64 %122
store double %124, double* %125
%126 = add nuw nsw i64 %122, 1
%127 = icmp eq i64 %126, %21
br i1 %127, label %128, label %121
128: ; preds = %121, %118
%129 = add nuw nsw i64 %59, 1
%130 = icmp eq i64 %129, %18
br i1 %130, label %131, label %58
131: ; preds = %128
%132 = tail call i64 @malloc(i32 %47)
%133 = inttoptr i64 %132 to double*
%134 = icmp ne i64 %132, 0
%135 = zext i1 %134 to i32
%136 = tail call i32 @assert(i32 %135)
%137 = icmp sgt i64 %21, 0
br i1 %137, label %138, label %192
138: ; preds = %131
%139 = icmp ult i64 %21, 4
br i1 %139, label %184, label %140
140: ; preds = %138
%141 = and i64 %21, -4
%142 = and i64 %50, 1
%143 = icmp ult i64 %48, 4
br i1 %143, label %170, label %144
144: ; preds = %140
%145 = and i64 %50, 9223372036854775806
br label %146
146: ; preds = %146, %144
%147 = phi i64 [ 0, %144 ], [ %166, %146 ]
%148 = phi <2 x i64> [ <i64 0, i64 1>, %144 ], [ %167, %146 ]
%149 = phi i64 [ 0, %144 ], [ %168, %146 ]
%150 = add <2 x i64> %148, <i64 2, i64 2>
%151 = sitofp <2 x i64> %148 to <2 x double>
%152 = sitofp <2 x i64> %150 to <2 x double>
%153 = getelementptr inbounds double, double* %133, i64 %147
%154 = bitcast double* %153 to <2 x double>*
store <2 x double> %151, <2 x double>* %154
%155 = getelementptr inbounds double, double* %153, i64 2
%156 = bitcast double* %155 to <2 x double>*
store <2 x double> %152, <2 x double>* %156
%157 = or i64 %147, 4
%158 = add <2 x i64> %148, <i64 4, i64 4>
%159 = add <2 x i64> %148, <i64 6, i64 6>
%160 = sitofp <2 x i64> %158 to <2 x double>
%161 = sitofp <2 x i64> %159 to <2 x double>
%162 = getelementptr inbounds double, double* %133, i64 %157
%163 = bitcast double* %162 to <2 x double>*
store <2 x double> %160, <2 x double>* %163
%164 = getelementptr inbounds double, double* %162, i64 2
%165 = bitcast double* %164 to <2 x double>*
store <2 x double> %161, <2 x double>* %165
%166 = add nuw i64 %147, 8
%167 = add <2 x i64> %148, <i64 8, i64 8>
%168 = add i64 %149, 2
%169 = icmp eq i64 %168, %145
br i1 %169, label %170, label %146
170: ; preds = %146, %140
%171 = phi i64 [ 0, %140 ], [ %166, %146 ]
%172 = phi <2 x i64> [ <i64 0, i64 1>, %140 ], [ %167, %146 ]
%173 = icmp eq i64 %142, 0
br i1 %173, label %182, label %174
174: ; preds = %170
%175 = add <2 x i64> %172, <i64 2, i64 2>
%176 = sitofp <2 x i64> %172 to <2 x double>
%177 = sitofp <2 x i64> %175 to <2 x double>
%178 = getelementptr inbounds double, double* %133, i64 %171
%179 = bitcast double* %178 to <2 x double>*
store <2 x double> %176, <2 x double>* %179
%180 = getelementptr inbounds double, double* %178, i64 2
%181 = bitcast double* %180 to <2 x double>*
store <2 x double> %177, <2 x double>* %181
br label %182
182: ; preds = %170, %174
%183 = icmp eq i64 %21, %141
br i1 %183, label %192, label %184
184: ; preds = %138, %182
%185 = phi i64 [ 0, %138 ], [ %141, %182 ]
br label %186
186: ; preds = %184, %186
%187 = phi i64 [ %190, %186 ], [ %185, %184 ]
%188 = sitofp i64 %187 to double
%189 = getelementptr inbounds double, double* %133, i64 %187
store double %188, double* %189
%190 = add nuw nsw i64 %187, 1
%191 = icmp eq i64 %190, %21
br i1 %191, label %192, label %186
192: ; preds = %186, %182, %131
%193 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([35 x i8], [35 x i8]* @.str.5, i64 0, i64 0), i64 %18, i64 %21)
%194 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([34 x i8], [34 x i8]* @.str.6, i64 0, i64 0), i64 %21)
%195 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([34 x i8], [34 x i8]* @.str.7, i64 0, i64 0), i64 %11)
%196 = tail call i32 @loopParCollapse(i64 %11, double** %42, double* %133, i64 %18, i64 %21, i64 %21)
%197 = icmp eq i32 %196, 1
br i1 %197, label %198, label %201
198: ; preds = %192
%199 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([59 x i8], [59 x i8]* @str.10, i64 0, i64 0))
%200 = tail call i32 @exit(i32 -1)
unreachable
201: ; preds = %192
%202 = tail call i32 @loopParNested(i64 %11, double** %42, double* %133, i64 %18, i64 %21, i64 %21)
%203 = icmp eq i32 %202, 1
br i1 %203, label %204, label %207
204: ; preds = %201
%205 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([59 x i8], [59 x i8]* @str, i64 0, i64 0))
%206 = tail call i32 @exit(i32 -1)
unreachable
207: ; preds = %201
ret i32 0
}