#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 */
double cos(int);
int /*<<< orphan*/ free(double *);
scalar_t__ malloc(size_t);
int /*<<< orphan*/ printf(char *, double);
double sin(int);
int main(int argc, char *argv[]) {
  int n = 10000;
  double *restrict a;
  double *restrict b;
  double *restrict c;
  size_t bytes = n * sizeof(double);
  a = (double *)malloc(bytes);
  b = (double *)malloc(bytes);
  c = (double *)malloc(bytes);
  int i;
  for (i = 0; i < n; i++) {
    a[i] = sin(i) * sin(i);
    b[i] = cos(i) * cos(i);
  }
#pragma acc kernels copyin(a [0:n], b [0:n]), copyout(c [0:n])
  for (i = 0; i < n; i++) {
    c[i] = a[i] + b[i];
  }
  double sum = 0.0;
  for (i = 0; i < n; i++) {
    sum += c[i];
  }
  sum = sum / n;
  printf("final result: %f\n", sum);
  free(a);
  free(b);
  free(c);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x2710,-0x14(%rbp)
movslq -0x14(%rbp),%rax
shl    $0x3,%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rdi
call   1060 <malloc@plt>
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rdi
call   1060 <malloc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x38(%rbp),%rdi
call   1060 <malloc@plt>
mov    %rax,-0x30(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    121d <main+0xcd>
mov    -0x3c(%rbp),%edi
call   1050 <sin@plt>
movsd  %xmm0,-0x58(%rbp)
mov    -0x3c(%rbp),%edi
call   1050 <sin@plt>
movaps %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x3c(%rbp),%edi
call   1070 <cos@plt>
movsd  %xmm0,-0x50(%rbp)
mov    -0x3c(%rbp),%edi
call   1070 <cos@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    11a7 <main+0x57>
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1265 <main+0x115>
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x3c(%rbp),%rcx
addsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1224 <main+0xd4>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    12a5 <main+0x155>
mov    -0x30(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1274 <main+0x124>
movsd  -0x48(%rbp),%xmm0
cvtsi2sdl -0x14(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
lea    0xd3c(%rip),%rdi
call   1040 <printf@plt>
mov    -0x20(%rbp),%rdi
call   1030 <free@plt>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    $0x13880,%edi
call   1060 <malloc@plt>
mov    %rax,%r14
mov    $0x13880,%edi
call   1060 <malloc@plt>
mov    %rax,%r15
mov    $0x13880,%edi
call   1060 <malloc@plt>
mov    %rax,%r12
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
nop
mov    %ebx,%edi
call   1050 <sin@plt>
movsd  %xmm0,0x8(%rsp)
mov    %ebx,%edi
call   1050 <sin@plt>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,(%r14,%rbx,8)
mov    %ebx,%edi
call   1070 <cos@plt>
movsd  %xmm0,0x8(%rsp)
mov    %ebx,%edi
call   1070 <cos@plt>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,(%r15,%rbx,8)
lea    0x1(%rbx),%ebp
mov    %ebp,%edi
call   1050 <sin@plt>
movsd  %xmm0,0x8(%rsp)
mov    %ebp,%edi
call   1050 <sin@plt>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%r14,%rbx,8)
mov    %ebp,%edi
call   1070 <cos@plt>
movsd  %xmm0,0x8(%rsp)
mov    %ebp,%edi
call   1070 <cos@plt>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%r15,%rbx,8)
add    $0x2,%rbx
cmp    $0x2710,%rbx
jne    1190 <main+0x40>
lea    0x13880(%r12),%rcx
lea    0x13880(%r14),%rax
lea    0x13880(%r15),%rdx
cmp    %rax,%r12
setb   %sil
cmp    %rcx,%r14
setb   %bl
cmp    %rdx,%r12
setb   %al
cmp    %rcx,%r15
setb   %cl
test   %bl,%sil
jne    12df <main+0x18f>
and    %cl,%al
jne    12df <main+0x18f>
mov    $0x6,%eax
nopl   0x0(%rax,%rax,1)
movupd -0x30(%r14,%rax,8),%xmm0
movupd -0x20(%r14,%rax,8),%xmm1
movupd -0x30(%r15,%rax,8),%xmm2
addpd  %xmm0,%xmm2
movupd -0x20(%r15,%rax,8),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm2,-0x30(%r12,%rax,8)
movupd %xmm0,-0x20(%r12,%rax,8)
movupd -0x10(%r14,%rax,8),%xmm0
movupd (%r14,%rax,8),%xmm1
movupd -0x10(%r15,%rax,8),%xmm2
addpd  %xmm0,%xmm2
movupd (%r15,%rax,8),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm2,-0x10(%r12,%rax,8)
movupd %xmm0,(%r12,%rax,8)
add    $0x8,%rax
cmp    $0x2716,%rax
jne    1270 <main+0x120>
jmp    134d <main+0x1fd>
mov    $0x3,%eax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  -0x18(%r14,%rax,8),%xmm0
addsd  -0x18(%r15,%rax,8),%xmm0
movsd  %xmm0,-0x18(%r12,%rax,8)
movsd  -0x10(%r14,%rax,8),%xmm0
addsd  -0x10(%r15,%rax,8),%xmm0
movsd  %xmm0,-0x10(%r12,%rax,8)
movsd  -0x8(%r14,%rax,8),%xmm0
addsd  -0x8(%r15,%rax,8),%xmm0
movsd  %xmm0,-0x8(%r12,%rax,8)
movsd  (%r14,%rax,8),%xmm0
addsd  (%r15,%rax,8),%xmm0
movsd  %xmm0,(%r12,%rax,8)
add    $0x4,%rax
cmp    $0x2713,%rax
jne    12f0 <main+0x1a0>
xorpd  %xmm0,%xmm0
mov    $0x7,%eax
cs nopw 0x0(%rax,%rax,1)
addsd  -0x38(%r12,%rax,8),%xmm0
addsd  -0x30(%r12,%rax,8),%xmm0
addsd  -0x28(%r12,%rax,8),%xmm0
addsd  -0x20(%r12,%rax,8),%xmm0
addsd  -0x18(%r12,%rax,8),%xmm0
addsd  -0x10(%r12,%rax,8),%xmm0
addsd  -0x8(%r12,%rax,8),%xmm0
addsd  (%r12,%rax,8),%xmm0
add    $0x8,%rax
cmp    $0x2717,%rax
jne    1360 <main+0x210>
divsd  0xc55(%rip),%xmm0
lea    0xc56(%rip),%rdi
call   1040 <printf@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r15,%rdi
call   1030 <free@plt>
mov    %r12,%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [18 x i8] c"final result: %f\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca double*
%8 = alloca double*
%9 = alloca double*
%10 = alloca i64
%11 = alloca i32
%12 = alloca double
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
store i32 10000, i32* %6
%13 = load i32, i32* %6
%14 = sext i32 %13 to i64
%15 = mul i64 %14, 8
store i64 %15, i64* %10
%16 = load i64, i64* %10
%17 = call i64 @malloc(i64 %16)
%18 = inttoptr i64 %17 to double*
store double* %18, double** %7
%19 = load i64, i64* %10
%20 = call i64 @malloc(i64 %19)
%21 = inttoptr i64 %20 to double*
store double* %21, double** %8
%22 = load i64, i64* %10
%23 = call i64 @malloc(i64 %22)
%24 = inttoptr i64 %23 to double*
store double* %24, double** %9
store i32 0, i32* %11
br label %25
25: ; preds = %48, %2
%26 = load i32, i32* %11
%27 = load i32, i32* %6
%28 = icmp slt i32 %26, %27
br i1 %28, label %29, label %51
29: ; preds = %25
%30 = load i32, i32* %11
%31 = call double @sin(i32 %30)
%32 = load i32, i32* %11
%33 = call double @sin(i32 %32)
%34 = fmul double %31, %33
%35 = load double*, double** %7
%36 = load i32, i32* %11
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds double, double* %35, i64 %37
store double %34, double* %38
%39 = load i32, i32* %11
%40 = call double @cos(i32 %39)
%41 = load i32, i32* %11
%42 = call double @cos(i32 %41)
%43 = fmul double %40, %42
%44 = load double*, double** %8
%45 = load i32, i32* %11
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds double, double* %44, i64 %46
store double %43, double* %47
br label %48
48: ; preds = %29
%49 = load i32, i32* %11
%50 = add nsw i32 %49, 1
store i32 %50, i32* %11
br label %25
51: ; preds = %25
store i32 0, i32* %11
br label %52
52: ; preds = %72, %51
%53 = load i32, i32* %11
%54 = load i32, i32* %6
%55 = icmp slt i32 %53, %54
br i1 %55, label %56, label %75
56: ; preds = %52
%57 = load double*, double** %7
%58 = load i32, i32* %11
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds double, double* %57, i64 %59
%61 = load double, double* %60
%62 = load double*, double** %8
%63 = load i32, i32* %11
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds double, double* %62, i64 %64
%66 = load double, double* %65
%67 = fadd double %61, %66
%68 = load double*, double** %9
%69 = load i32, i32* %11
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds double, double* %68, i64 %70
store double %67, double* %71
br label %72
72: ; preds = %56
%73 = load i32, i32* %11
%74 = add nsw i32 %73, 1
store i32 %74, i32* %11
br label %52
75: ; preds = %52
store double 0.000000e+00, double* %12
store i32 0, i32* %11
br label %76
76: ; preds = %88, %75
%77 = load i32, i32* %11
%78 = load i32, i32* %6
%79 = icmp slt i32 %77, %78
br i1 %79, label %80, label %91
80: ; preds = %76
%81 = load double*, double** %9
%82 = load i32, i32* %11
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds double, double* %81, i64 %83
%85 = load double, double* %84
%86 = load double, double* %12
%87 = fadd double %86, %85
store double %87, double* %12
br label %88
88: ; preds = %80
%89 = load i32, i32* %11
%90 = add nsw i32 %89, 1
store i32 %90, i32* %11
br label %76
91: ; preds = %76
%92 = load double, double* %12
%93 = load i32, i32* %6
%94 = sitofp i32 %93 to double
%95 = fdiv double %92, %94
store double %95, double* %12
%96 = load double, double* %12
%97 = call i32 @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0), double %96)
%98 = load double*, double** %7
%99 = call i32 @free(double* %98)
%100 = load double*, double** %8
%101 = call i32 @free(double* %100)
%102 = load double*, double** %9
%103 = call i32 @free(double* %102)
ret i32 0
}

LLVM IR (-O2):
@.str = [18 x i8] c"final result: %f\0A\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = tail call i64 @malloc(i64 80000)
%4 = inttoptr i64 %3 to double*
%5 = inttoptr i64 %3 to i8*
%6 = tail call i64 @malloc(i64 80000)
%7 = inttoptr i64 %6 to double*
%8 = inttoptr i64 %6 to i8*
%9 = tail call i64 @malloc(i64 80000)
br label %10
10: ; preds = %10, %2
%11 = phi i64 [ 0, %2 ], [ %31, %10 ]
%12 = trunc i64 %11 to i32
%13 = tail call double @sin(i32 %12)
%14 = tail call double @sin(i32 %12)
%15 = fmul double %13, %14
%16 = getelementptr inbounds double, double* %4, i64 %11
store double %15, double* %16
%17 = tail call double @cos(i32 %12)
%18 = tail call double @cos(i32 %12)
%19 = fmul double %17, %18
%20 = getelementptr inbounds double, double* %7, i64 %11
store double %19, double* %20
%21 = or i64 %11, 1
%22 = trunc i64 %21 to i32
%23 = tail call double @sin(i32 %22)
%24 = tail call double @sin(i32 %22)
%25 = fmul double %23, %24
%26 = getelementptr inbounds double, double* %4, i64 %21
store double %25, double* %26
%27 = tail call double @cos(i32 %22)
%28 = tail call double @cos(i32 %22)
%29 = fmul double %27, %28
%30 = getelementptr inbounds double, double* %7, i64 %21
store double %29, double* %30
%31 = add nuw nsw i64 %11, 2
%32 = icmp eq i64 %31, 10000
br i1 %32, label %33, label %10
33: ; preds = %10
%34 = inttoptr i64 %9 to double*
%35 = inttoptr i64 %9 to i8*
%36 = getelementptr double, double* %34, i64 10000
%37 = bitcast double* %36 to i8*
%38 = getelementptr double, double* %4, i64 10000
%39 = bitcast double* %38 to i8*
%40 = getelementptr double, double* %7, i64 10000
%41 = bitcast double* %40 to i8*
%42 = icmp ult i8* %35, %39
%43 = icmp ult i8* %5, %37
%44 = and i1 %42, %43
%45 = icmp ult i8* %35, %41
%46 = icmp ult i8* %8, %37
%47 = and i1 %45, %46
%48 = or i1 %44, %47
br i1 %48, label %90, label %49
49: ; preds = %33, %49
%50 = phi i64 [ %88, %49 ], [ 0, %33 ]
%51 = getelementptr inbounds double, double* %4, i64 %50
%52 = bitcast double* %51 to <2 x double>*
%53 = load <2 x double>, <2 x double>* %52
%54 = getelementptr inbounds double, double* %51, i64 2
%55 = bitcast double* %54 to <2 x double>*
%56 = load <2 x double>, <2 x double>* %55
%57 = getelementptr inbounds double, double* %7, i64 %50
%58 = bitcast double* %57 to <2 x double>*
%59 = load <2 x double>, <2 x double>* %58
%60 = getelementptr inbounds double, double* %57, i64 2
%61 = bitcast double* %60 to <2 x double>*
%62 = load <2 x double>, <2 x double>* %61
%63 = fadd <2 x double> %53, %59
%64 = fadd <2 x double> %56, %62
%65 = getelementptr inbounds double, double* %34, i64 %50
%66 = bitcast double* %65 to <2 x double>*
store <2 x double> %63, <2 x double>* %66
%67 = getelementptr inbounds double, double* %65, i64 2
%68 = bitcast double* %67 to <2 x double>*
store <2 x double> %64, <2 x double>* %68
%69 = or i64 %50, 4
%70 = getelementptr inbounds double, double* %4, i64 %69
%71 = bitcast double* %70 to <2 x double>*
%72 = load <2 x double>, <2 x double>* %71
%73 = getelementptr inbounds double, double* %70, i64 2
%74 = bitcast double* %73 to <2 x double>*
%75 = load <2 x double>, <2 x double>* %74
%76 = getelementptr inbounds double, double* %7, i64 %69
%77 = bitcast double* %76 to <2 x double>*
%78 = load <2 x double>, <2 x double>* %77
%79 = getelementptr inbounds double, double* %76, i64 2
%80 = bitcast double* %79 to <2 x double>*
%81 = load <2 x double>, <2 x double>* %80
%82 = fadd <2 x double> %72, %78
%83 = fadd <2 x double> %75, %81
%84 = getelementptr inbounds double, double* %34, i64 %69
%85 = bitcast double* %84 to <2 x double>*
store <2 x double> %82, <2 x double>* %85
%86 = getelementptr inbounds double, double* %84, i64 2
%87 = bitcast double* %86 to <2 x double>*
store <2 x double> %83, <2 x double>* %87
%88 = add nuw nsw i64 %50, 8
%89 = icmp eq i64 %88, 10000
br i1 %89, label %121, label %49
90: ; preds = %33, %90
%91 = phi i64 [ %119, %90 ], [ 0, %33 ]
%92 = getelementptr inbounds double, double* %4, i64 %91
%93 = load double, double* %92
%94 = getelementptr inbounds double, double* %7, i64 %91
%95 = load double, double* %94
%96 = fadd double %93, %95
%97 = getelementptr inbounds double, double* %34, i64 %91
store double %96, double* %97
%98 = or i64 %91, 1
%99 = getelementptr inbounds double, double* %4, i64 %98
%100 = load double, double* %99
%101 = getelementptr inbounds double, double* %7, i64 %98
%102 = load double, double* %101
%103 = fadd double %100, %102
%104 = getelementptr inbounds double, double* %34, i64 %98
store double %103, double* %104
%105 = or i64 %91, 2
%106 = getelementptr inbounds double, double* %4, i64 %105
%107 = load double, double* %106
%108 = getelementptr inbounds double, double* %7, i64 %105
%109 = load double, double* %108
%110 = fadd double %107, %109
%111 = getelementptr inbounds double, double* %34, i64 %105
store double %110, double* %111
%112 = or i64 %91, 3
%113 = getelementptr inbounds double, double* %4, i64 %112
%114 = load double, double* %113
%115 = getelementptr inbounds double, double* %7, i64 %112
%116 = load double, double* %115
%117 = fadd double %114, %116
%118 = getelementptr inbounds double, double* %34, i64 %112
store double %117, double* %118
%119 = add nuw nsw i64 %91, 4
%120 = icmp eq i64 %119, 10000
br i1 %120, label %121, label %90
121: ; preds = %49, %90
br label %122
122: ; preds = %122, %121
%123 = phi i64 [ 0, %121 ], [ %156, %122 ]
%124 = phi double [ 0.000000e+00, %121 ], [ %155, %122 ]
%125 = getelementptr inbounds double, double* %34, i64 %123
%126 = load double, double* %125
%127 = fadd double %124, %126
%128 = or i64 %123, 1
%129 = getelementptr inbounds double, double* %34, i64 %128
%130 = load double, double* %129
%131 = fadd double %127, %130
%132 = or i64 %123, 2
%133 = getelementptr inbounds double, double* %34, i64 %132
%134 = load double, double* %133
%135 = fadd double %131, %134
%136 = or i64 %123, 3
%137 = getelementptr inbounds double, double* %34, i64 %136
%138 = load double, double* %137
%139 = fadd double %135, %138
%140 = or i64 %123, 4
%141 = getelementptr inbounds double, double* %34, i64 %140
%142 = load double, double* %141
%143 = fadd double %139, %142
%144 = or i64 %123, 5
%145 = getelementptr inbounds double, double* %34, i64 %144
%146 = load double, double* %145
%147 = fadd double %143, %146
%148 = or i64 %123, 6
%149 = getelementptr inbounds double, double* %34, i64 %148
%150 = load double, double* %149
%151 = fadd double %147, %150
%152 = or i64 %123, 7
%153 = getelementptr inbounds double, double* %34, i64 %152
%154 = load double, double* %153
%155 = fadd double %151, %154
%156 = add nuw nsw i64 %123, 8
%157 = icmp eq i64 %156, 10000
br i1 %157, label %158, label %122
158: ; preds = %122
%159 = fdiv double %155, 1.000000e+04
%160 = tail call i32 @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0), double %159)
%161 = tail call i32 @free(double* %4)
%162 = tail call i32 @free(double* %7)
%163 = tail call i32 @free(double* %34)
ret i32 0
}