#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*/ fflush(int /*<<< orphan*/);
int /*<<< orphan*/ free(int *);
scalar_t__ malloc(int);
int /*<<< orphan*/ stdout;
int main(void) {
  int i;
  int N = 2048 * 2048;
  int *A = (int *)malloc(N * sizeof(int));
  int *B = (int *)malloc(N * sizeof(int));
  for (i = 0; i < N; i++) {
    A[i] = i;
  }
#pragma scop
  {
#pragma species kernel A[0 : N - 1] | element->B[0 : N - 1] | element
    for (i = 0; i < N; i++) {
      B[i] = A[i] + 3;
    }
#pragma species endkernel example06_k1
  }
#pragma endscop
  free(A);
  free(B);
  fflush(stdout);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x400000,-0xc(%rbp)
movslq -0xc(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1040 <malloc@plt>
mov    %rax,-0x18(%rbp)
movslq -0xc(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1040 <malloc@plt>
mov    %rax,-0x20(%rbp)
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    119b <main+0x6b>
mov    -0x8(%rbp),%edx
mov    -0x18(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1173 <main+0x43>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11d5 <main+0xa5>
mov    -0x18(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
add    $0x3,%edx
mov    -0x20(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    11a2 <main+0x72>
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
mov    -0x20(%rbp),%rdi
call   1030 <free@plt>
mov    0x2df2(%rip),%rax
mov    (%rax),%edi
call   1050 <fflush@plt>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r14
push   %rbx
push   %rax
mov    $0x1000000,%edi
call   1040 <malloc@plt>
mov    %rax,%rbx
mov    $0x1000000,%edi
call   1040 <malloc@plt>
mov    %rax,%r14
movdqa 0xeaa(%rip),%xmm0
mov    $0x1c,%eax
movdqa 0xeac(%rip),%xmm8
movdqa 0xeb3(%rip),%xmm9
movdqa 0xeba(%rip),%xmm10
movdqa 0xec2(%rip),%xmm4
movdqa 0xeca(%rip),%xmm5
movdqa 0xed2(%rip),%xmm6
movdqa 0xeda(%rip),%xmm7
movdqa 0xee2(%rip),%xmm1
xchg   %ax,%ax
movdqa %xmm0,%xmm2
paddd  %xmm8,%xmm2
movdqu %xmm0,-0x70(%rbx,%rax,4)
movdqu %xmm2,-0x60(%rbx,%rax,4)
movdqa %xmm0,%xmm2
paddd  %xmm9,%xmm2
movdqa %xmm0,%xmm3
paddd  %xmm10,%xmm3
movdqu %xmm2,-0x50(%rbx,%rax,4)
movdqu %xmm3,-0x40(%rbx,%rax,4)
movdqa %xmm0,%xmm2
paddd  %xmm4,%xmm2
movdqa %xmm0,%xmm3
paddd  %xmm5,%xmm3
movdqu %xmm2,-0x30(%rbx,%rax,4)
movdqu %xmm3,-0x20(%rbx,%rax,4)
movdqa %xmm0,%xmm2
paddd  %xmm6,%xmm2
movdqa %xmm0,%xmm3
paddd  %xmm7,%xmm3
movdqu %xmm2,-0x10(%rbx,%rax,4)
movdqu %xmm3,(%rbx,%rax,4)
paddd  %xmm1,%xmm0
add    $0x20,%rax
cmp    $0x40001c,%rax
jne    11a0 <main+0x70>
mov    %rbx,%rax
add    $0x1000000,%rax
cmp    %rax,%r14
jae    127c <main+0x14c>
mov    %r14,%rax
add    $0x1000000,%rax
cmp    %rax,%rbx
jae    127c <main+0x14c>
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
mov    (%rbx,%rax,4),%ecx
add    $0x3,%ecx
mov    %ecx,(%r14,%rax,4)
mov    0x4(%rbx,%rax,4),%ecx
add    $0x3,%ecx
mov    %ecx,0x4(%r14,%rax,4)
mov    0x8(%rbx,%rax,4),%ecx
add    $0x3,%ecx
mov    %ecx,0x8(%r14,%rax,4)
mov    0xc(%rbx,%rax,4),%ecx
add    $0x3,%ecx
mov    %ecx,0xc(%r14,%rax,4)
add    $0x4,%rax
cmp    $0x400000,%rax
jne    1240 <main+0x110>
jmp    12de <main+0x1ae>
xor    %eax,%eax
movdqa 0xe0a(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
movdqu (%rbx,%rax,4),%xmm1
movdqu 0x10(%rbx,%rax,4),%xmm2
paddd  %xmm0,%xmm1
paddd  %xmm0,%xmm2
movdqu %xmm1,(%r14,%rax,4)
movdqu %xmm2,0x10(%r14,%rax,4)
movdqu 0x20(%rbx,%rax,4),%xmm1
movdqu 0x30(%rbx,%rax,4),%xmm2
paddd  %xmm0,%xmm1
paddd  %xmm0,%xmm2
movdqu %xmm1,0x20(%r14,%rax,4)
movdqu %xmm2,0x30(%r14,%rax,4)
add    $0x10,%rax
cmp    $0x400000,%rax
jne    1290 <main+0x160>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    0x2ceb(%rip),%rax
mov    (%rax),%edi
call   1050 <fflush@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@stdout = global i32 0
define i32 @main() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32*
%5 = alloca i32*
store i32 0, i32* %1
store i32 4194304, i32* %3
%6 = load i32, i32* %3
%7 = sext i32 %6 to i64
%8 = mul i64 %7, 4
%9 = trunc i64 %8 to i32
%10 = call i64 @malloc(i32 %9)
%11 = inttoptr i64 %10 to i32*
store i32* %11, i32** %4
%12 = load i32, i32* %3
%13 = sext i32 %12 to i64
%14 = mul i64 %13, 4
%15 = trunc i64 %14 to i32
%16 = call i64 @malloc(i32 %15)
%17 = inttoptr i64 %16 to i32*
store i32* %17, i32** %5
store i32 0, i32* %2
br label %18
18: ; preds = %28, %0
%19 = load i32, i32* %2
%20 = load i32, i32* %3
%21 = icmp slt i32 %19, %20
br i1 %21, label %22, label %31
22: ; preds = %18
%23 = load i32, i32* %2
%24 = load i32*, i32** %4
%25 = load i32, i32* %2
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds i32, i32* %24, i64 %26
store i32 %23, i32* %27
br label %28
28: ; preds = %22
%29 = load i32, i32* %2
%30 = add nsw i32 %29, 1
store i32 %30, i32* %2
br label %18
31: ; preds = %18
store i32 0, i32* %2
br label %32
32: ; preds = %47, %31
%33 = load i32, i32* %2
%34 = load i32, i32* %3
%35 = icmp slt i32 %33, %34
br i1 %35, label %36, label %50
36: ; preds = %32
%37 = load i32*, i32** %4
%38 = load i32, i32* %2
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i32, i32* %37, i64 %39
%41 = load i32, i32* %40
%42 = add nsw i32 %41, 3
%43 = load i32*, i32** %5
%44 = load i32, i32* %2
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i32, i32* %43, i64 %45
store i32 %42, i32* %46
br label %47
47: ; preds = %36
%48 = load i32, i32* %2
%49 = add nsw i32 %48, 1
store i32 %49, i32* %2
br label %32
50: ; preds = %32
%51 = load i32*, i32** %4
%52 = call i32 @free(i32* %51)
%53 = load i32*, i32** %5
%54 = call i32 @free(i32* %53)
%55 = load i32, i32* @stdout
%56 = call i32 @fflush(i32 %55)
ret i32 0
}

LLVM IR (-O2):
@stdout = global i32 0
define i32 @main() {
%1 = tail call i64 @malloc(i32 16777216)
%2 = inttoptr i64 %1 to i32*
%3 = inttoptr i64 %1 to i8*
%4 = tail call i64 @malloc(i32 16777216)
br label %5
5: ; preds = %5, %0
%6 = phi i64 [ 0, %0 ], [ %34, %5 ]
%7 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %0 ], [ %35, %5 ]
%8 = add <4 x i32> %7, <i32 4, i32 4, i32 4, i32 4>
%9 = getelementptr inbounds i32, i32* %2, i64 %6
%10 = bitcast i32* %9 to <4 x i32>*
store <4 x i32> %7, <4 x i32>* %10
%11 = getelementptr inbounds i32, i32* %9, i64 4
%12 = bitcast i32* %11 to <4 x i32>*
store <4 x i32> %8, <4 x i32>* %12
%13 = or i64 %6, 8
%14 = add <4 x i32> %7, <i32 8, i32 8, i32 8, i32 8>
%15 = add <4 x i32> %7, <i32 12, i32 12, i32 12, i32 12>
%16 = getelementptr inbounds i32, i32* %2, i64 %13
%17 = bitcast i32* %16 to <4 x i32>*
store <4 x i32> %14, <4 x i32>* %17
%18 = getelementptr inbounds i32, i32* %16, i64 4
%19 = bitcast i32* %18 to <4 x i32>*
store <4 x i32> %15, <4 x i32>* %19
%20 = or i64 %6, 16
%21 = add <4 x i32> %7, <i32 16, i32 16, i32 16, i32 16>
%22 = add <4 x i32> %7, <i32 20, i32 20, i32 20, i32 20>
%23 = getelementptr inbounds i32, i32* %2, i64 %20
%24 = bitcast i32* %23 to <4 x i32>*
store <4 x i32> %21, <4 x i32>* %24
%25 = getelementptr inbounds i32, i32* %23, i64 4
%26 = bitcast i32* %25 to <4 x i32>*
store <4 x i32> %22, <4 x i32>* %26
%27 = or i64 %6, 24
%28 = add <4 x i32> %7, <i32 24, i32 24, i32 24, i32 24>
%29 = add <4 x i32> %7, <i32 28, i32 28, i32 28, i32 28>
%30 = getelementptr inbounds i32, i32* %2, i64 %27
%31 = bitcast i32* %30 to <4 x i32>*
store <4 x i32> %28, <4 x i32>* %31
%32 = getelementptr inbounds i32, i32* %30, i64 4
%33 = bitcast i32* %32 to <4 x i32>*
store <4 x i32> %29, <4 x i32>* %33
%34 = add nuw nsw i64 %6, 32
%35 = add <4 x i32> %7, <i32 32, i32 32, i32 32, i32 32>
%36 = icmp eq i64 %34, 4194304
br i1 %36, label %37, label %5
37: ; preds = %5
%38 = inttoptr i64 %4 to i32*
%39 = inttoptr i64 %4 to i8*
%40 = getelementptr i32, i32* %38, i64 4194304
%41 = bitcast i32* %40 to i8*
%42 = getelementptr i32, i32* %2, i64 4194304
%43 = bitcast i32* %42 to i8*
%44 = icmp ult i8* %39, %43
%45 = icmp ult i8* %3, %41
%46 = and i1 %44, %45
br i1 %46, label %76, label %47
47: ; preds = %37, %47
%48 = phi i64 [ %74, %47 ], [ 0, %37 ]
%49 = getelementptr inbounds i32, i32* %2, i64 %48
%50 = bitcast i32* %49 to <4 x i32>*
%51 = load <4 x i32>, <4 x i32>* %50
%52 = getelementptr inbounds i32, i32* %49, i64 4
%53 = bitcast i32* %52 to <4 x i32>*
%54 = load <4 x i32>, <4 x i32>* %53
%55 = add nsw <4 x i32> %51, <i32 3, i32 3, i32 3, i32 3>
%56 = add nsw <4 x i32> %54, <i32 3, i32 3, i32 3, i32 3>
%57 = getelementptr inbounds i32, i32* %38, i64 %48
%58 = bitcast i32* %57 to <4 x i32>*
store <4 x i32> %55, <4 x i32>* %58
%59 = getelementptr inbounds i32, i32* %57, i64 4
%60 = bitcast i32* %59 to <4 x i32>*
store <4 x i32> %56, <4 x i32>* %60
%61 = or i64 %48, 8
%62 = getelementptr inbounds i32, i32* %2, i64 %61
%63 = bitcast i32* %62 to <4 x i32>*
%64 = load <4 x i32>, <4 x i32>* %63
%65 = getelementptr inbounds i32, i32* %62, i64 4
%66 = bitcast i32* %65 to <4 x i32>*
%67 = load <4 x i32>, <4 x i32>* %66
%68 = add nsw <4 x i32> %64, <i32 3, i32 3, i32 3, i32 3>
%69 = add nsw <4 x i32> %67, <i32 3, i32 3, i32 3, i32 3>
%70 = getelementptr inbounds i32, i32* %38, i64 %61
%71 = bitcast i32* %70 to <4 x i32>*
store <4 x i32> %68, <4 x i32>* %71
%72 = getelementptr inbounds i32, i32* %70, i64 4
%73 = bitcast i32* %72 to <4 x i32>*
store <4 x i32> %69, <4 x i32>* %73
%74 = add nuw nsw i64 %48, 16
%75 = icmp eq i64 %74, 4194304
br i1 %75, label %99, label %47
76: ; preds = %37, %76
%77 = phi i64 [ %97, %76 ], [ 0, %37 ]
%78 = getelementptr inbounds i32, i32* %2, i64 %77
%79 = load i32, i32* %78
%80 = add nsw i32 %79, 3
%81 = getelementptr inbounds i32, i32* %38, i64 %77
store i32 %80, i32* %81
%82 = or i64 %77, 1
%83 = getelementptr inbounds i32, i32* %2, i64 %82
%84 = load i32, i32* %83
%85 = add nsw i32 %84, 3
%86 = getelementptr inbounds i32, i32* %38, i64 %82
store i32 %85, i32* %86
%87 = or i64 %77, 2
%88 = getelementptr inbounds i32, i32* %2, i64 %87
%89 = load i32, i32* %88
%90 = add nsw i32 %89, 3
%91 = getelementptr inbounds i32, i32* %38, i64 %87
store i32 %90, i32* %91
%92 = or i64 %77, 3
%93 = getelementptr inbounds i32, i32* %2, i64 %92
%94 = load i32, i32* %93
%95 = add nsw i32 %94, 3
%96 = getelementptr inbounds i32, i32* %38, i64 %92
store i32 %95, i32* %96
%97 = add nuw nsw i64 %77, 4
%98 = icmp eq i64 %97, 4194304
br i1 %98, label %99, label %76
99: ; preds = %47, %76
%100 = tail call i32 @free(i32* %2)
%101 = tail call i32 @free(i32* %38)
%102 = load i32, i32* @stdout
%103 = tail call i32 @fflush(i32 %102)
ret i32 0
}