#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 */
struct timeval {
  int tv_sec;
  double tv_usec;
};

/* Variables and functions */
int /*<<< orphan*/ acc_device_default;
int /*<<< orphan*/ acc_init(int /*<<< orphan*/);
int /*<<< orphan*/ free(int *);
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
scalar_t__ malloc(int);
int /*<<< orphan*/ printf(char *, ...);
int rand();
int /*<<< orphan*/ srand(unsigned int);
scalar_t__ time(int /*<<< orphan*/);
int main() {
  int i, j, k;
  int product, known_product;
  int NI, NJ, NK;
  int error;
  int *input, *temp;
  struct timeval tim;
  double start, end;
  NK = 1 << 10;
  NJ = 1 << 10;
  NI = 64;
  error = 0;
  input = (int *)malloc(NK * NJ * NI * sizeof(int));
  temp = (int *)malloc(NK * NJ * NI * sizeof(int));
  acc_init(acc_device_default);
  srand((unsigned)time(0));
  for (k = 0; k < NK; k++) {
    for (j = 0; j < NJ; j++) {
      for (i = 0; i < NI; i++) {
        input[k * NJ * NI + j * NI + i] = rand() % 5 + 1;
      }
    }
  }
  product = 1;
  gettimeofday(&tim, NULL);
  start = tim.tv_sec * 1000 + (tim.tv_usec / 1000.0);
#pragma acc parallel copyin(input [0:NK * NJ * NI])                            \
    create(temp [0:NK * NJ * NI]) num_gangs(192) num_workers(8)                \
        vector_length(128)
  {
#pragma acc loop gang reduction(* : product)
    for (k = 0; k < NK; k++) {
#pragma acc loop worker
      for (j = 0; j < NJ; j++) {
#pragma acc loop vector
        for (i = 0; i < NI; i++)
          temp[k * NJ * NI + j * NI + i] = input[k * NJ * NI + j * NI + i];
        product *= temp[k * NJ * NI + j * NI];
      }
    }
  }
  gettimeofday(&tim, NULL);
  end = tim.tv_sec * 1000 + (tim.tv_usec / 1000.0);
  known_product = 1;
  for (k = 0; k < NK; k++) {
    for (j = 0; j < NJ; j++) {
      known_product *= input[k * NJ * NI + j * NI];
    }
  }
  if (product != known_product) {
    error++;
    printf("gang_worker * FAILED! product=%d, known_product=%d\n", product,
           known_product);
  }
  printf("gang_worker * execution time is :%.2lf: ms\n", end - start);
  if (error == 0)
    printf("gang_worker * SUCCESS!\n");
  free(input);
  free(temp);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x400,-0x24(%rbp)
movl   $0x400,-0x20(%rbp)
movl   $0x40,-0x1c(%rbp)
movl   $0x0,-0x28(%rbp)
mov    -0x24(%rbp),%eax
imul   -0x20(%rbp),%eax
imul   -0x1c(%rbp),%eax
cltq
shl    $0x2,%rax
mov    %eax,%edi
call   1080 <malloc@plt>
mov    %rax,-0x30(%rbp)
mov    -0x24(%rbp),%eax
imul   -0x20(%rbp),%eax
imul   -0x1c(%rbp),%eax
cltq
shl    $0x2,%rax
mov    %eax,%edi
call   1080 <malloc@plt>
mov    %rax,-0x38(%rbp)
mov    0x2df6(%rip),%rax
mov    (%rax),%edi
call   1090 <acc_init@plt>
xor    %edi,%edi
call   1070 <time@plt>
mov    %eax,%edi
call   1060 <srand@plt>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    129f <main+0x11f>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    128c <main+0x10c>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1279 <main+0xf9>
mov    $0x0,%al
call   10a0 <rand@plt>
mov    $0x5,%ecx
cltd
idiv   %ecx
add    $0x1,%edx
mov    -0x30(%rbp),%rax
mov    -0x10(%rbp),%ecx
imul   -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%esi
imul   -0x1c(%rbp),%esi
add    %esi,%ecx
add    -0x8(%rbp),%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    122c <main+0xac>
jmp    127e <main+0xfe>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1219 <main+0x99>
jmp    1291 <main+0x111>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1206 <main+0x86>
movl   $0x1,-0x14(%rbp)
lea    -0x48(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1050 <gettimeofday@plt>
imul   $0x3e8,-0x48(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  -0x40(%rbp),%xmm1
movsd  0xd35(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    13a7 <main+0x227>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1394 <main+0x214>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1361 <main+0x1e1>
mov    -0x30(%rbp),%rax
mov    -0x10(%rbp),%ecx
imul   -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%edx
imul   -0x1c(%rbp),%edx
add    %edx,%ecx
add    -0x8(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x38(%rbp),%rax
mov    -0x10(%rbp),%ecx
imul   -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%esi
imul   -0x1c(%rbp),%esi
add    %esi,%ecx
add    -0x8(%rbp),%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1305 <main+0x185>
mov    -0x38(%rbp),%rax
mov    -0x10(%rbp),%ecx
imul   -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%edx
imul   -0x1c(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
imul   -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    12f2 <main+0x172>
jmp    1399 <main+0x219>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    12df <main+0x15f>
lea    -0x48(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1050 <gettimeofday@plt>
imul   $0x3e8,-0x48(%rbp),%eax
cvtsi2sd %eax,%xmm0
movsd  -0x40(%rbp),%xmm1
movsd  0xc34(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movl   $0x1,-0x18(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    144c <main+0x2cc>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1439 <main+0x2b9>
mov    -0x30(%rbp),%rax
mov    -0x10(%rbp),%ecx
imul   -0x20(%rbp),%ecx
imul   -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%edx
imul   -0x1c(%rbp),%edx
add    %edx,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
imul   -0x18(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    13fa <main+0x27a>
jmp    143e <main+0x2be>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    13e7 <main+0x267>
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
je     1475 <main+0x2f5>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x14(%rbp),%esi
mov    -0x18(%rbp),%edx
lea    0xb9a(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
movsd  -0x58(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
lea    0xbb6(%rip),%rdi
mov    $0x1,%al
call   1040 <printf@plt>
cmpl   $0x0,-0x28(%rbp)
jne    14a5 <main+0x325>
lea    0xbca(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    $0x10000000,%edi
call   1090 <malloc@plt>
mov    %rax,%r14
mov    $0x10000000,%edi
call   1090 <malloc@plt>
mov    %rax,%r13
mov    0x2e21(%rip),%rax
mov    (%rax),%edi
call   10a0 <acc_init@plt>
xor    %edi,%edi
call   1080 <time@plt>
mov    %eax,%edi
call   1070 <srand@plt>
mov    %r14,%rbp
xor    %r12d,%r12d
nopw   0x0(%rax,%rax,1)
mov    %rbp,0x8(%rsp)
xor    %ebx,%ebx
nopw   0x0(%rax,%rax,1)
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
xor    %eax,%eax
call   10b0 <rand@plt>
cltq
imul   $0x66666667,%rax,%rcx
mov    %rcx,%rdx
shr    $0x3f,%rdx
sar    $0x21,%rcx
add    %edx,%ecx
lea    (%rcx,%rcx,4),%ecx
neg    %ecx
add    %ecx,%eax
add    $0x1,%eax
mov    %eax,0x0(%rbp,%r15,4)
add    $0x1,%r15
cmp    $0x40,%r15
jne    1200 <main+0x70>
add    $0x1,%rbx
add    $0x100,%rbp
cmp    $0x400,%rbx
jne    11f0 <main+0x60>
add    $0x1,%r12
mov    0x8(%rsp),%rbp
add    $0x40000,%rbp
cmp    $0x400,%r12
jne    11e0 <main+0x50>
xor    %r15d,%r15d
lea    0x18(%rsp),%rdi
xor    %esi,%esi
call   1060 <gettimeofday@plt>
imul   $0x3e8,0x18(%rsp),%eax
mov    %eax,0x8(%rsp)
movsd  0x20(%rsp),%xmm1
divsd  0xd70(%rip),%xmm1
lea    0xc(%r13),%r9
lea    0xc(%r14),%r10
mov    $0x1,%ebp
jmp    12bf <main+0x12f>
nop
add    $0x1,%r15
add    $0x40000,%r9
add    $0x40000,%r10
cmp    $0x400,%r15
je     14ad <main+0x31d>
mov    %r15,%r12
shl    $0x10,%r12
lea    0x40(%r12),%r11
mov    %r10,%rdx
mov    %r9,%rcx
xor    %eax,%eax
jmp    143a <main+0x2aa>
nopl   0x0(%rax,%rax,1)
lea    0x0(,%rdi,4),%rsi
movups (%r14,%rdi,4),%xmm0
movups %xmm0,0x0(%r13,%rdi,4)
mov    %rsi,%rbx
or     $0x10,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x20,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x30,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x40,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x50,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x60,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x70,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x80,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0x90,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0xa0,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0xb0,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0xc0,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0xd0,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
mov    %rsi,%rbx
or     $0xe0,%rbx
movups (%r14,%rbx,1),%xmm0
movups %xmm0,0x0(%r13,%rbx,1)
or     $0xf0,%rsi
movups (%r14,%rsi,1),%xmm0
movups %xmm0,0x0(%r13,%rsi,1)
imul   0x0(%r13,%rdi,4),%ebp
add    $0x1,%rax
add    $0x100,%rcx
add    $0x100,%rdx
cmp    $0x400,%rax
je     12a0 <main+0x110>
mov    %rax,%rsi
shl    $0x6,%rsi
lea    (%r12,%rsi,1),%rdi
add    %r11,%rsi
lea    (%r14,%rsi,4),%rbx
lea    0x0(,%rdi,4),%r8
add    %r13,%r8
cmp    %rbx,%r8
jae    12e0 <main+0x150>
lea    (%r14,%rdi,4),%rbx
lea    0x0(,%rsi,4),%rsi
add    %r13,%rsi
cmp    %rsi,%rbx
jae    12e0 <main+0x150>
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
mov    -0xc(%rdx,%rsi,4),%ebx
mov    %ebx,-0xc(%rcx,%rsi,4)
mov    -0x8(%rdx,%rsi,4),%ebx
mov    %ebx,-0x8(%rcx,%rsi,4)
mov    -0x4(%rdx,%rsi,4),%ebx
mov    %ebx,-0x4(%rcx,%rsi,4)
mov    (%rdx,%rsi,4),%ebx
mov    %ebx,(%rcx,%rsi,4)
add    $0x4,%rsi
cmp    $0x40,%rsi
jne    1480 <main+0x2f0>
jmp    1416 <main+0x286>
xorps  %xmm0,%xmm0
cvtsi2sdl 0x8(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
xor    %r15d,%r15d
lea    0x18(%rsp),%rdi
xor    %esi,%esi
movsd  %xmm1,0x8(%rsp)
call   1060 <gettimeofday@plt>
movsd  0x8(%rsp),%xmm1
imul   $0x3e8,0x18(%rsp),%eax
movsd  0x20(%rsp),%xmm0
divsd  0xb13(%rip),%xmm0
mov    %r14,%rcx
add    $0x300,%rcx
mov    $0x1,%edx
nopl   0x0(%rax)
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
imul   -0x300(%rcx,%rsi,1),%edx
ff
imul   -0x200(%rcx,%rsi,1),%edx
ff
imul   -0x100(%rcx,%rsi,1),%edx
ff
imul   (%rcx,%rsi,1),%edx
add    $0x400,%rsi
cmp    $0x40000,%rsi
jne    1510 <main+0x380>
add    $0x1,%r15
add    $0x40000,%rcx
cmp    $0x400,%r15
jne    1500 <main+0x370>
addsd  0x10(%rsp),%xmm1
cvtsi2sd %eax,%xmm2
addsd  %xmm2,%xmm0
cmp    %edx,%ebp
jne    1582 <main+0x3f2>
subsd  %xmm1,%xmm0
lea    0xacf(%rip),%rdi
mov    $0x1,%al
call   1050 <printf@plt>
lea    0xaed(%rip),%rdi
call   1040 <puts@plt>
jmp    15b8 <main+0x428>
lea    0xa7f(%rip),%rdi
mov    %ebp,%esi
xor    %eax,%eax
movsd  %xmm1,0x8(%rsp)
movsd  %xmm0,0x10(%rsp)
call   1050 <printf@plt>
movsd  0x10(%rsp),%xmm0
subsd  0x8(%rsp),%xmm0
lea    0xa8b(%rip),%rdi
mov    $0x1,%al
call   1050 <printf@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r13,%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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