#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ kernel_code;
typedef int cl_uint;
typedef int /*<<< orphan*/ cl_program;
typedef int /*<<< orphan*/ cl_platform_id;
typedef unsigned int cl_mem;
typedef int /*<<< orphan*/ cl_kernel;
typedef int /*<<< orphan*/ cl_event;
typedef int /*<<< orphan*/ cl_device_id;
typedef int /*<<< orphan*/ cl_context_properties;
typedef int /*<<< orphan*/ cl_context;
typedef int /*<<< orphan*/ cl_command_queue;

/* Variables and functions */
int /*<<< orphan*/ CL_CONTEXT_PLATFORM;
int /*<<< orphan*/ CL_DEVICE_TYPE_CPU;
int /*<<< orphan*/ CL_MEM_USE_HOST_PTR;
int /*<<< orphan*/ CL_PLATFORM_NAME;
int /*<<< orphan*/ CL_TRUE;
int /*<<< orphan*/ clBuildProgram(int /*<<< orphan*/, int, int /*<<< orphan*/ *,
                                  int /*<<< orphan*/, int /*<<< orphan*/,
                                  int /*<<< orphan*/);
unsigned int clCreateBuffer(int /*<<< orphan*/, int /*<<< orphan*/, size_t,
                            float *, int *);
int /*<<< orphan*/ clCreateCommandQueue(int /*<<< orphan*/, int /*<<< orphan*/,
                                        int /*<<< orphan*/, int *);
int /*<<< orphan*/ clCreateContext(int /*<<< orphan*/ *, int,
                                   int /*<<< orphan*/ *, int /*<<< orphan*/,
                                   int /*<<< orphan*/, int *);
int /*<<< orphan*/ clCreateKernel(int /*<<< orphan*/, char *, int *);
int /*<<< orphan*/ clCreateProgramWithSource(int /*<<< orphan*/, int,
                                             char const **, size_t *, int *);
int /*<<< orphan*/ clEnqueueNDRangeKernel(
    int /*<<< orphan*/, int /*<<< orphan*/, int, int /*<<< orphan*/, size_t *,
    size_t *, int /*<<< orphan*/, int /*<<< orphan*/, int /*<<< orphan*/ *);
int /*<<< orphan*/ clEnqueueReadBuffer(int /*<<< orphan*/, unsigned int,
                                       int /*<<< orphan*/, int /*<<< orphan*/,
                                       size_t, float *, int /*<<< orphan*/,
                                       int /*<<< orphan*/,
                                       int /*<<< orphan*/ *);
int /*<<< orphan*/ clGetDeviceIDs(int /*<<< orphan*/, int /*<<< orphan*/, int,
                                  int /*<<< orphan*/ *, int *);
int /*<<< orphan*/ clGetPlatformIDs(int, int /*<<< orphan*/ *, int *);
int /*<<< orphan*/ clGetPlatformInfo(int /*<<< orphan*/, int /*<<< orphan*/,
                                     int, char *, int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseCommandQueue(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseContext(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseEvent(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseKernel(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseMemObject(unsigned int);
int /*<<< orphan*/ clReleaseProgram(int /*<<< orphan*/);
int /*<<< orphan*/ clSetKernelArg(int /*<<< orphan*/, int, int, unsigned int *);
int clWaitForEvents(int, int /*<<< orphan*/ *);
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ free(float *);
scalar_t__ malloc(unsigned int);
int /*<<< orphan*/ printf(char *, ...);
int /*<<< orphan*/ strcmp(char *, char *);
int main() {
  int i, j;
  int err;
  char buffer[256];
  unsigned int n = 1024;
  cl_uint nplatforms;
  cl_platform_id *platforms;
  cl_platform_id platform;
  clGetPlatformIDs(0, 0, &nplatforms);
  platforms = (cl_platform_id *)malloc(nplatforms * sizeof(cl_platform_id));
  clGetPlatformIDs(nplatforms, platforms, 0);
  for (i = 0; i < nplatforms; i++) {
    platform = platforms[i];
    clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 256, buffer, 0);
    if (!strcmp(buffer, "coprthr"))
      break;
  }
  if (i < nplatforms)
    platform = platforms[i];
  else
    exit(1);
  cl_uint ndevices;
  cl_device_id *devices;
  cl_device_id dev;
  clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, 0, &ndevices);
  devices = (cl_device_id *)malloc(ndevices * sizeof(cl_device_id));
  clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, ndevices, devices, 0);
  if (ndevices)
    dev = devices[0];
  else
    exit(1);
  cl_context_properties ctxprop[3] = {
      (cl_context_properties)CL_CONTEXT_PLATFORM,
      (cl_context_properties)platform, (cl_context_properties)0};
  cl_context ctx = clCreateContext(ctxprop, 1, &dev, 0, 0, &err);
  cl_command_queue cmdq = clCreateCommandQueue(ctx, dev, 0, &err);
  size_t aa_sz = n * n * sizeof(float);
  size_t b_sz = n * sizeof(float);
  size_t c_sz = n * sizeof(float);
  float *aa = (float *)malloc(n * n * sizeof(float));
  float *b = (float *)malloc(n * sizeof(float));
  float *c = (float *)malloc(n * sizeof(float));
  printf("XXX aa b c %p %p %p\n", aa, b, c);
  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
      aa[i * n + j] = 1.1f * i * j;
  for (i = 0; i < n; i++)
    b[i] = 2.2f * i;
  for (i = 0; i < n; i++)
    c[i] = 0.0f;
  cl_mem aa_buf = clCreateBuffer(ctx, CL_MEM_USE_HOST_PTR, aa_sz, aa, &err);
  cl_mem b_buf = clCreateBuffer(ctx, CL_MEM_USE_HOST_PTR, b_sz, b, &err);
  cl_mem c_buf = clCreateBuffer(ctx, CL_MEM_USE_HOST_PTR, c_sz, c, &err);
  const char kernel_code[] =
      "__kernel void matvecmult_kern(\n"
      "   uint n,__global float* aa,__global float* b,__global float* c )\n"
      "{\n"
      "   int i = get_global_id(0);\n"
      "   int j;\n"
      "   float tmp = 0.0f;\n"
      "   for(j=0;j<n;j++) tmp += aa[i*n+j] * b[j];\n"
      "   c[i] = aa[i*n+i];\n"
      "}\n";
  const char *src[1] = {kernel_code};
  size_t src_sz = sizeof(kernel_code);
  cl_program prg =
      clCreateProgramWithSource(ctx, 1, (const char **)&src, &src_sz, &err);
  clBuildProgram(prg, 1, &dev, 0, 0, 0);
  cl_kernel krn = clCreateKernel(prg, "matvecmult_kern", &err);
  clSetKernelArg(krn, 0, sizeof(cl_uint), &n);
  clSetKernelArg(krn, 1, sizeof(cl_mem), &aa_buf);
  clSetKernelArg(krn, 2, sizeof(cl_mem), &b_buf);
  clSetKernelArg(krn, 3, sizeof(cl_mem), &c_buf);
  size_t gtdsz[] = {n};
  size_t ltdsz[] = {16};
  cl_event ev[10];
  clEnqueueNDRangeKernel(cmdq, krn, 1, 0, gtdsz, ltdsz, 0, 0, &ev[0]);
  clEnqueueReadBuffer(cmdq, c_buf, CL_TRUE, 0, c_sz, c, 0, 0, &ev[1]);
  err = clWaitForEvents(2, ev);
  for (i = 0; i < n; i++)
    printf("c[%d] %f\n", i, c[i]);
  printf("clWaitForEvents returned %d\n", err);
  clReleaseEvent(ev[1]);
  clReleaseEvent(ev[0]);
  clReleaseKernel(krn);
  clReleaseProgram(prg);
  clReleaseMemObject(aa_buf);
  clReleaseMemObject(b_buf);
  clReleaseMemObject(c_buf);
  clReleaseCommandQueue(cmdq);
  clReleaseContext(ctx);
  free(aa);
  free(b);
  free(c);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x2e0,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x400,-0x114(%rbp)
xor    %edi,%edi
xor    %eax,%eax
mov    %eax,%esi
lea    -0x118(%rbp),%rdx
call   10c0 <clGetPlatformIDs@plt>
movslq -0x118(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1130 <malloc@plt>
mov    %rax,-0x120(%rbp)
mov    -0x118(%rbp),%edi
mov    -0x120(%rbp),%rsi
xor    %eax,%eax
mov    %eax,%edx
call   10c0 <clGetPlatformIDs@plt>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x118(%rbp),%eax
jge    1376 <main+0xe6>
mov    -0x120(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x124(%rbp)
mov    -0x120(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    (%rax,%rcx,4),%edi
mov    0x2ca4(%rip),%rax
mov    (%rax),%esi
lea    -0x110(%rbp),%rcx
mov    $0x100,%edx
xor    %r8d,%r8d
call   10e0 <clGetPlatformInfo@plt>
lea    -0x110(%rbp),%rdi
lea    0xcb8(%rip),%rsi
call   1100 <strcmp@plt>
cmp    $0x0,%eax
jne    1363 <main+0xd3>
jmp    1376 <main+0xe6>
jmp    1368 <main+0xd8>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    12f4 <main+0x64>
mov    -0x8(%rbp),%eax
cmp    -0x118(%rbp),%eax
jge    139e <main+0x10e>
mov    -0x120(%rbp),%rax
movslq -0x8(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x124(%rbp)
jmp    13a8 <main+0x118>
mov    $0x1,%edi
call   11a0 <exit@plt>
mov    -0x124(%rbp),%edi
mov    0x2c13(%rip),%rax
mov    (%rax),%esi
xor    %edx,%edx
xor    %eax,%eax
mov    %eax,%ecx
lea    -0x128(%rbp),%r8
call   1090 <clGetDeviceIDs@plt>
movslq -0x128(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1130 <malloc@plt>
mov    %rax,-0x130(%rbp)
mov    -0x124(%rbp),%edi
mov    0x2bd9(%rip),%rax
mov    (%rax),%esi
mov    -0x128(%rbp),%edx
mov    -0x130(%rbp),%rcx
xor    %eax,%eax
mov    %eax,%r8d
call   1090 <clGetDeviceIDs@plt>
cmpl   $0x0,-0x128(%rbp)
je     1429 <main+0x199>
mov    -0x130(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x134(%rbp)
jmp    1433 <main+0x1a3>
mov    $0x1,%edi
call   11a0 <exit@plt>
mov    0x2b86(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x140(%rbp)
mov    -0x124(%rbp),%eax
mov    %eax,-0x13c(%rbp)
movl   $0x0,-0x138(%rbp)
lea    -0x140(%rbp),%rdi
mov    $0x1,%esi
lea    -0x134(%rbp),%rdx
xor    %r8d,%r8d
lea    -0x10(%rbp),%r9
mov    %r8d,%ecx
call   10f0 <clCreateContext@plt>
mov    %eax,-0x144(%rbp)
mov    -0x144(%rbp),%edi
mov    -0x134(%rbp),%esi
xor    %edx,%edx
lea    -0x10(%rbp),%rcx
call   10b0 <clCreateCommandQueue@plt>
mov    %eax,-0x148(%rbp)
mov    -0x114(%rbp),%eax
imul   -0x114(%rbp),%eax
mov    %eax,%eax
shl    $0x2,%rax
mov    %rax,-0x150(%rbp)
mov    -0x114(%rbp),%eax
shl    $0x2,%rax
mov    %rax,-0x158(%rbp)
mov    -0x114(%rbp),%eax
shl    $0x2,%rax
mov    %rax,-0x160(%rbp)
mov    -0x114(%rbp),%eax
imul   -0x114(%rbp),%eax
mov    %eax,%eax
shl    $0x2,%rax
mov    %eax,%edi
call   1130 <malloc@plt>
mov    %rax,-0x168(%rbp)
mov    -0x114(%rbp),%eax
shl    $0x2,%rax
mov    %eax,%edi
call   1130 <malloc@plt>
mov    %rax,-0x170(%rbp)
mov    -0x114(%rbp),%eax
shl    $0x2,%rax
mov    %eax,%edi
call   1130 <malloc@plt>
mov    %rax,-0x178(%rbp)
mov    -0x168(%rbp),%rsi
mov    -0x170(%rbp),%rdx
mov    -0x178(%rbp),%rcx
lea    0xaca(%rip),%rdi
mov    $0x0,%al
call   10d0 <printf@plt>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x114(%rbp),%eax
jae    15cf <main+0x33f>
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x114(%rbp),%eax
jae    15bc <main+0x32c>
cvtsi2ssl -0x8(%rbp),%xmm1
movss  0xa7e(%rip),%xmm0
mulss  %xmm1,%xmm0
cvtsi2ssl -0xc(%rbp),%xmm1
mulss  %xmm1,%xmm0
mov    -0x168(%rbp),%rax
mov    -0x8(%rbp),%ecx
imul   -0x114(%rbp),%ecx
add    -0xc(%rbp),%ecx
mov    %ecx,%ecx
movss  %xmm0,(%rax,%rcx,4)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    156a <main+0x2da>
jmp    15c1 <main+0x331>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1554 <main+0x2c4>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x114(%rbp),%eax
jae    1614 <main+0x384>
cvtsi2ssl -0x8(%rbp),%xmm1
movss  0xa0e(%rip),%xmm0
mulss  %xmm1,%xmm0
mov    -0x170(%rbp),%rax
movslq -0x8(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    15d6 <main+0x346>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x114(%rbp),%eax
jae    164b <main+0x3bb>
mov    -0x178(%rbp),%rax
movslq -0x8(%rbp),%rcx
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    161b <main+0x38b>
mov    -0x144(%rbp),%edi
mov    0x2988(%rip),%rax
mov    (%rax),%esi
mov    -0x150(%rbp),%rdx
mov    -0x168(%rbp),%rcx
lea    -0x10(%rbp),%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,-0x17c(%rbp)
mov    -0x144(%rbp),%edi
mov    0x295c(%rip),%rax
mov    (%rax),%esi
mov    -0x158(%rbp),%rdx
mov    -0x170(%rbp),%rcx
lea    -0x10(%rbp),%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,-0x180(%rbp)
mov    -0x144(%rbp),%edi
mov    0x2930(%rip),%rax
mov    (%rax),%esi
mov    -0x160(%rbp),%rdx
mov    -0x178(%rbp),%rcx
lea    -0x10(%rbp),%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,-0x184(%rbp)
lea    -0x270(%rbp),%rdi
lea    0x983(%rip),%rsi
mov    $0xe5,%edx
call   1110 <memcpy@plt>
lea    -0x270(%rbp),%rax
mov    %rax,-0x278(%rbp)
movq   $0xe5,-0x280(%rbp)
mov    -0x144(%rbp),%edi
lea    -0x278(%rbp),%rdx
mov    $0x1,%esi
lea    -0x280(%rbp),%rcx
lea    -0x10(%rbp),%r8
call   1050 <clCreateProgramWithSource@plt>
mov    %eax,-0x284(%rbp)
mov    -0x284(%rbp),%edi
mov    $0x1,%esi
lea    -0x134(%rbp),%rdx
xor    %r9d,%r9d
mov    %r9d,%ecx
mov    %r9d,%r8d
call   1030 <clBuildProgram@plt>
mov    -0x284(%rbp),%edi
lea    0x8d0(%rip),%rsi
lea    -0x10(%rbp),%rdx
call   1190 <clCreateKernel@plt>
mov    %eax,-0x288(%rbp)
mov    -0x288(%rbp),%edi
xor    %esi,%esi
mov    $0x4,%edx
lea    -0x114(%rbp),%rcx
call   11b0 <clSetKernelArg@plt>
mov    -0x288(%rbp),%edi
mov    $0x1,%esi
mov    $0x4,%edx
lea    -0x17c(%rbp),%rcx
call   11b0 <clSetKernelArg@plt>
mov    -0x288(%rbp),%edi
mov    $0x2,%esi
mov    $0x4,%edx
lea    -0x180(%rbp),%rcx
call   11b0 <clSetKernelArg@plt>
mov    -0x288(%rbp),%edi
mov    $0x3,%esi
mov    $0x4,%edx
lea    -0x184(%rbp),%rcx
call   11b0 <clSetKernelArg@plt>
mov    -0x114(%rbp),%eax
mov    %rax,-0x290(%rbp)
mov    0x963(%rip),%rax
mov    %rax,-0x298(%rbp)
mov    -0x148(%rbp),%edi
mov    -0x288(%rbp),%esi
lea    -0x290(%rbp),%r8
lea    -0x298(%rbp),%r9
lea    -0x2c0(%rbp),%rax
mov    $0x1,%edx
xor    %ecx,%ecx
movl   $0x0,(%rsp)
movl   $0x0,0x8(%rsp)
mov    %rax,0x10(%rsp)
call   10a0 <clEnqueueNDRangeKernel@plt>
mov    -0x148(%rbp),%edi
mov    -0x184(%rbp),%esi
mov    0x27a8(%rip),%rax
mov    (%rax),%edx
mov    -0x160(%rbp),%r8
mov    -0x178(%rbp),%r9
lea    -0x2c0(%rbp),%rax
add    $0x4,%rax
xor    %ecx,%ecx
movl   $0x0,(%rsp)
movl   $0x0,0x8(%rsp)
mov    %rax,0x10(%rsp)
call   1140 <clEnqueueReadBuffer@plt>
lea    -0x2c0(%rbp),%rsi
mov    $0x2,%edi
call   1180 <clWaitForEvents@plt>
mov    %eax,-0x10(%rbp)
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x114(%rbp),%eax
jae    18d3 <main+0x643>
mov    -0x8(%rbp),%esi
mov    -0x178(%rbp),%rax
movslq -0x8(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
lea    0x777(%rip),%rdi
mov    $0x1,%al
call   10d0 <printf@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1891 <main+0x601>
mov    -0x10(%rbp),%esi
lea    0x762(%rip),%rdi
mov    $0x0,%al
call   10d0 <printf@plt>
mov    -0x2bc(%rbp),%edi
call   1170 <clReleaseEvent@plt>
mov    -0x2c0(%rbp),%edi
call   1170 <clReleaseEvent@plt>
mov    -0x288(%rbp),%edi
call   1060 <clReleaseKernel@plt>
mov    -0x284(%rbp),%edi
call   1080 <clReleaseProgram@plt>
mov    -0x17c(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x180(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x184(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x148(%rbp),%edi
call   1120 <clReleaseCommandQueue@plt>
mov    -0x144(%rbp),%edi
call   1150 <clReleaseContext@plt>
mov    -0x168(%rbp),%rdi
call   1040 <free@plt>
mov    -0x170(%rbp),%rdi
call   1040 <free@plt>
mov    -0x178(%rbp),%rdi
call   1040 <free@plt>
mov    -0x4(%rbp),%eax
add    $0x2e0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x278,%rsp
movl   $0x400,0x8(%rsp)
xor    %ebp,%ebp
lea    0x4(%rsp),%rdx
xor    %edi,%edi
xor    %esi,%esi
call   10c0 <clGetPlatformIDs@plt>
mov    0x4(%rsp),%edi
shl    $0x2,%edi
call   1130 <malloc@plt>
mov    %rax,%rbx
mov    0x4(%rsp),%edi
mov    %rax,%rsi
xor    %edx,%edx
call   10c0 <clGetPlatformIDs@plt>
mov    0x4(%rsp),%eax
test   %eax,%eax
jle    1334 <main+0xa4>
xor    %ebp,%ebp
mov    0x2ce9(%rip),%r15
lea    0x90(%rsp),%r14
movabs $0x72687472706f63,%r12
nopl   0x0(%rax)
mov    (%rbx,%rbp,4),%edi
mov    (%r15),%esi
mov    $0x100,%edx
mov    %r14,%rcx
xor    %r8d,%r8d
call   10f0 <clGetPlatformInfo@plt>
cmp    %r12,0x90(%rsp)
je     1330 <main+0xa0>
add    $0x1,%rbp
movslq 0x4(%rsp),%rax
cmp    %rax,%rbp
jl     1300 <main+0x70>
jmp    1334 <main+0xa4>
mov    0x4(%rsp),%eax
cmp    %eax,%ebp
jge    17e4 <main+0x554>
mov    %ebp,%eax
mov    (%rbx,%rax,4),%r14d
mov    0x2c7f(%rip),%r15
mov    (%r15),%esi
xor    %ebx,%ebx
lea    0x14(%rsp),%r8
mov    %r14d,%edi
xor    %edx,%edx
xor    %ecx,%ecx
call   1090 <clGetDeviceIDs@plt>
mov    0x14(%rsp),%edi
shl    $0x2,%edi
call   1130 <malloc@plt>
mov    %rax,%rbp
mov    (%r15),%esi
mov    0x14(%rsp),%edx
mov    %r14d,%edi
mov    %rax,%rcx
xor    %r8d,%r8d
call   1090 <clGetDeviceIDs@plt>
cmpl   $0x0,0x14(%rsp)
je     17e4 <main+0x554>
mov    0x0(%rbp),%eax
mov    %eax,0x10(%rsp)
mov    0x2c24(%rip),%rax
mov    (%rax),%eax
mov    %eax,0x2c(%rsp)
mov    %r14d,0x30(%rsp)
movl   $0x0,0x34(%rsp)
lea    0x2c(%rsp),%rdi
lea    0x10(%rsp),%rdx
lea    0x18(%rsp),%rbp
mov    $0x1,%esi
xor    %ecx,%ecx
xor    %r8d,%r8d
mov    %rbp,%r9
call   1100 <clCreateContext@plt>
mov    %eax,%r14d
mov    0x10(%rsp),%esi
mov    %eax,%edi
xor    %edx,%edx
mov    %rbp,%rcx
call   10b0 <clCreateCommandQueue@plt>
mov    %eax,0x1c(%rsp)
mov    $0x400000,%edi
call   1130 <malloc@plt>
mov    %rax,%r13
mov    $0x1000,%edi
call   1130 <malloc@plt>
mov    %rax,%rbp
mov    $0x1000,%edi
call   1130 <malloc@plt>
mov    %rax,%r12
lea    0xc7b(%rip),%rdi
mov    %r13,%rsi
mov    %rbp,%rdx
mov    %rax,%rcx
xor    %eax,%eax
call   10d0 <printf@plt>
mov    %r13,%rax
add    $0x10,%rax
movss  0xbcc(%rip),%xmm0
movdqa 0xbd4(%rip),%xmm1
movdqa 0xbdc(%rip),%xmm2
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
xorps  %xmm3,%xmm3
cvtsi2ss %ebx,%xmm3
mulss  %xmm0,%xmm3
shufps $0x0,%xmm3,%xmm3
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movd   %ecx,%xmm4
lea    0x1(%rcx),%edx
pshufd $0x50,%xmm4,%xmm5
por    %xmm1,%xmm5
movd   %edx,%xmm6
pshufd $0x0,%xmm4,%xmm7
punpckldq %xmm6,%xmm4
punpcklqdq %xmm5,%xmm4
por    %xmm2,%xmm7
cvtdq2ps %xmm4,%xmm4
cvtdq2ps %xmm7,%xmm5
mulps  %xmm3,%xmm4
mulps  %xmm3,%xmm5
movups %xmm4,-0x10(%rax,%rcx,4)
movups %xmm5,(%rax,%rcx,4)
add    $0x8,%rcx
cmp    $0x400,%rcx
jne    1470 <main+0x1e0>
add    $0x1,%ebx
add    $0x1000,%rax
cmp    $0x400,%ebx
jne    1450 <main+0x1c0>
movdqa 0xb60(%rip),%xmm0
mov    $0xc,%eax
movdqa 0xb63(%rip),%xmm1
movaps 0xb6c(%rip),%xmm2
movdqa 0xb74(%rip),%xmm3
movdqa 0xb7c(%rip),%xmm4
movdqa 0xb84(%rip),%xmm5
nopl   0x0(%rax)
movdqa %xmm0,%xmm6
paddd  %xmm1,%xmm6
cvtdq2ps %xmm0,%xmm7
cvtdq2ps %xmm6,%xmm6
mulps  %xmm2,%xmm7
mulps  %xmm2,%xmm6
movups %xmm7,-0x30(%rbp,%rax,4)
movups %xmm6,-0x20(%rbp,%rax,4)
movdqa %xmm0,%xmm6
paddd  %xmm3,%xmm6
movdqa %xmm0,%xmm7
paddd  %xmm4,%xmm7
cvtdq2ps %xmm6,%xmm6
cvtdq2ps %xmm7,%xmm7
mulps  %xmm2,%xmm6
mulps  %xmm2,%xmm7
movups %xmm6,-0x10(%rbp,%rax,4)
movups %xmm7,0x0(%rbp,%rax,4)
paddd  %xmm5,%xmm0
add    $0x10,%rax
cmp    $0x40c,%rax
jne    1500 <main+0x270>
mov    $0x1000,%edx
mov    %r12,%rdi
xor    %esi,%esi
call   10e0 <memset@plt>
mov    0x2a76(%rip),%rbx
mov    (%rbx),%esi
lea    0x18(%rsp),%r15
mov    $0x400000,%edx
mov    %r14d,%edi
mov    %r13,0x38(%rsp)
mov    %r13,%rcx
mov    %r15,%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,0x24(%rsp)
mov    (%rbx),%esi
mov    $0x1000,%edx
mov    %r14d,%edi
mov    %rbp,%rcx
mov    %r15,%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,0x20(%rsp)
mov    (%rbx),%esi
mov    $0x1000,%edx
mov    %r14d,%edi
mov    %r12,%rcx
mov    %r15,%r8
call   1070 <clCreateBuffer@plt>
mov    %eax,0xc(%rsp)
lea    0xb1a(%rip),%rsi
lea    0x190(%rsp),%rbx
mov    $0xe5,%edx
mov    %rbx,%rdi
call   1110 <memcpy@plt>
mov    %rbx,0x58(%rsp)
movq   $0xe5,0x50(%rsp)
lea    0x58(%rsp),%rdx
lea    0x50(%rsp),%rcx
mov    %r14d,0x28(%rsp)
mov    %r14d,%edi
mov    $0x1,%esi
mov    %r15,%r8
call   1050 <clCreateProgramWithSource@plt>
mov    %eax,%r13d
lea    0x10(%rsp),%rdx
mov    %eax,%edi
mov    $0x1,%esi
xor    %ecx,%ecx
xor    %r8d,%r8d
xor    %r9d,%r9d
call   1030 <clBuildProgram@plt>
lea    0xa7a(%rip),%rsi
mov    %r13d,%edi
mov    %r15,%rdx
call   1190 <clCreateKernel@plt>
mov    %eax,%r15d
lea    0x8(%rsp),%rcx
mov    %eax,%edi
xor    %esi,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
lea    0x24(%rsp),%rcx
mov    %r15d,%edi
mov    $0x1,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
lea    0x20(%rsp),%rcx
mov    %r15d,%edi
mov    $0x2,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
lea    0xc(%rsp),%rcx
mov    %r15d,%edi
mov    $0x3,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
mov    0x8(%rsp),%eax
mov    %rax,0x48(%rsp)
movq   $0x10,0x40(%rsp)
sub    $0x8,%rsp
lea    0x68(%rsp),%r14
lea    0x50(%rsp),%r8
lea    0x48(%rsp),%r9
mov    0x24(%rsp),%ebx
mov    %ebx,%edi
mov    %r15d,%esi
mov    $0x1,%edx
xor    %ecx,%ecx
push   %r14
push   $0x0
push   $0x0
call   10a0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    0xc(%rsp),%esi
mov    0x2908(%rip),%rax
mov    (%rax),%edx
lea    0x64(%rsp),%rax
sub    $0x8,%rsp
mov    $0x1000,%r8d
mov    %ebx,%edi
xor    %ecx,%ecx
mov    %r12,%r9
push   %rax
push   $0x0
push   $0x0
call   1140 <clEnqueueReadBuffer@plt>
add    $0x20,%rsp
mov    $0x2,%edi
mov    %r14,%rsi
call   1180 <clWaitForEvents@plt>
mov    %eax,0x18(%rsp)
cmpl   $0x0,0x8(%rsp)
je     1757 <main+0x4c7>
xor    %ebx,%ebx
lea    0x98e(%rip),%r14
nopw   0x0(%rax,%rax,1)
movss  (%r12,%rbx,4),%xmm0
cvtss2sd %xmm0,%xmm0
mov    %r14,%rdi
mov    %ebx,%esi
mov    $0x1,%al
call   10d0 <printf@plt>
add    $0x1,%rbx
mov    0x8(%rsp),%eax
cmp    %rax,%rbx
jb     1730 <main+0x4a0>
mov    0x18(%rsp),%eax
lea    0x961(%rip),%rdi
mov    %eax,%esi
xor    %eax,%eax
call   10d0 <printf@plt>
mov    0x64(%rsp),%edi
call   1170 <clReleaseEvent@plt>
mov    0x60(%rsp),%edi
call   1170 <clReleaseEvent@plt>
mov    %r15d,%edi
call   1060 <clReleaseKernel@plt>
mov    %r13d,%edi
call   1080 <clReleaseProgram@plt>
mov    0x24(%rsp),%edi
call   1160 <clReleaseMemObject@plt>
mov    0x20(%rsp),%edi
call   1160 <clReleaseMemObject@plt>
mov    0xc(%rsp),%edi
call   1160 <clReleaseMemObject@plt>
mov    0x1c(%rsp),%edi
call   1120 <clReleaseCommandQueue@plt>
mov    0x28(%rsp),%edi
call   1150 <clReleaseContext@plt>
mov    0x38(%rsp),%rdi
call   1040 <free@plt>
mov    %rbp,%rdi
call   1040 <free@plt>
mov    %r12,%rdi
call   1040 <free@plt>
xor    %eax,%eax
add    $0x278,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    $0x1,%edi
call   11a0 <exit@plt>

LLVM IR (-O0):
@CL_PLATFORM_NAME = global i32 0
@.str = [8 x i8] c"coprthr\00"
@CL_DEVICE_TYPE_CPU = global i32 0
@CL_CONTEXT_PLATFORM = global i32 0
@.str.1 = [21 x i8] c"XXX aa b c %p %p %p\0A\00"
@CL_MEM_USE_HOST_PTR = global i32 0
@__const.main.kernel_code = [229 x i8] c"__kernel void matvecmult_kern(\0A uint n,__global float* aa,__global float* b,__global float* c )\0A{\0A int i = get_global_id(0);\0A int j;\0A float tmp = 0.0f;\0A for(j=0;j<n;j++) tmp += aa[i*n+j] * b[j];\0A c[i] = aa[i*n+i];\0A}\0A\00"
@.str.2 = [16 x i8] c"matvecmult_kern\00"
@__const.main.ltdsz = [1 x i64] [i64 16]
@CL_TRUE = global i32 0
@.str.3 = [10 x i8] c"c[%d] %f\0A\00"
@.str.4 = [29 x i8] c"clWaitForEvents returned %d\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca [256 x i8]
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32*
%12 = alloca i32
%13 = alloca [3 x i32]
%14 = alloca i32
%15 = alloca i32
%16 = alloca i64
%17 = alloca i64
%18 = alloca i64
%19 = alloca float*
%20 = alloca float*
%21 = alloca float*
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
%25 = alloca [229 x i8]
%26 = alloca [1 x i8*]
%27 = alloca i64
%28 = alloca i32
%29 = alloca i32
%30 = alloca [1 x i64]
%31 = alloca [1 x i64]
%32 = alloca [10 x i32]
store i32 0, i32* %1
store i32 1024, i32* %6
%33 = call i32 @clGetPlatformIDs(i32 0, i32* null, i32* %7)
%34 = load i32, i32* %7
%35 = sext i32 %34 to i64
%36 = mul i64 %35, 4
%37 = trunc i64 %36 to i32
%38 = call i64 @malloc(i32 %37)
%39 = inttoptr i64 %38 to i32*
store i32* %39, i32** %8
%40 = load i32, i32* %7
%41 = load i32*, i32** %8
%42 = call i32 @clGetPlatformIDs(i32 %40, i32* %41, i32* null)
store i32 0, i32* %2
br label %43
43: ; preds = %66, %0
%44 = load i32, i32* %2
%45 = load i32, i32* %7
%46 = icmp slt i32 %44, %45
br i1 %46, label %47, label %69
47: ; preds = %43
%48 = load i32*, i32** %8
%49 = load i32, i32* %2
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds i32, i32* %48, i64 %50
%52 = load i32, i32* %51
store i32 %52, i32* %9
%53 = load i32*, i32** %8
%54 = load i32, i32* %2
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %53, i64 %55
%57 = load i32, i32* %56
%58 = load i32, i32* @CL_PLATFORM_NAME
%59 = getelementptr inbounds [256 x i8], [256 x i8]* %5, i64 0, i64 0
%60 = call i32 @clGetPlatformInfo(i32 %57, i32 %58, i32 256, i8* %59, i32 0)
%61 = getelementptr inbounds [256 x i8], [256 x i8]* %5, i64 0, i64 0
%62 = call i32 @strcmp(i8* %61, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0))
%63 = icmp ne i32 %62, 0
br i1 %63, label %65, label %64
64: ; preds = %47
br label %69
65: ; preds = %47
br label %66
66: ; preds = %65
%67 = load i32, i32* %2
%68 = add nsw i32 %67, 1
store i32 %68, i32* %2
br label %43
69: ; preds = %64, %43
%70 = load i32, i32* %2
%71 = load i32, i32* %7
%72 = icmp slt i32 %70, %71
br i1 %72, label %73, label %79
73: ; preds = %69
%74 = load i32*, i32** %8
%75 = load i32, i32* %2
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds i32, i32* %74, i64 %76
%78 = load i32, i32* %77
store i32 %78, i32* %9
br label %81
79: ; preds = %69
%80 = call i32 @exit(i32 1)
unreachable
81: ; preds = %73
%82 = load i32, i32* %9
%83 = load i32, i32* @CL_DEVICE_TYPE_CPU
%84 = call i32 @clGetDeviceIDs(i32 %82, i32 %83, i32 0, i32* null, i32* %10)
%85 = load i32, i32* %10
%86 = sext i32 %85 to i64
%87 = mul i64 %86, 4
%88 = trunc i64 %87 to i32
%89 = call i64 @malloc(i32 %88)
%90 = inttoptr i64 %89 to i32*
store i32* %90, i32** %11
%91 = load i32, i32* %9
%92 = load i32, i32* @CL_DEVICE_TYPE_CPU
%93 = load i32, i32* %10
%94 = load i32*, i32** %11
%95 = call i32 @clGetDeviceIDs(i32 %91, i32 %92, i32 %93, i32* %94, i32* null)
%96 = load i32, i32* %10
%97 = icmp ne i32 %96, 0
br i1 %97, label %98, label %102
98: ; preds = %81
%99 = load i32*, i32** %11
%100 = getelementptr inbounds i32, i32* %99, i64 0
%101 = load i32, i32* %100
store i32 %101, i32* %12
br label %104
102: ; preds = %81
%103 = call i32 @exit(i32 1)
unreachable
104: ; preds = %98
%105 = getelementptr inbounds [3 x i32], [3 x i32]* %13, i64 0, i64 0
%106 = load i32, i32* @CL_CONTEXT_PLATFORM
store i32 %106, i32* %105
%107 = getelementptr inbounds i32, i32* %105, i64 1
%108 = load i32, i32* %9
store i32 %108, i32* %107
%109 = getelementptr inbounds i32, i32* %107, i64 1
store i32 0, i32* %109
%110 = getelementptr inbounds [3 x i32], [3 x i32]* %13, i64 0, i64 0
%111 = call i32 @clCreateContext(i32* %110, i32 1, i32* %12, i32 0, i32 0, i32* %4)
store i32 %111, i32* %14
%112 = load i32, i32* %14
%113 = load i32, i32* %12
%114 = call i32 @clCreateCommandQueue(i32 %112, i32 %113, i32 0, i32* %4)
store i32 %114, i32* %15
%115 = load i32, i32* %6
%116 = load i32, i32* %6
%117 = mul i32 %115, %116
%118 = zext i32 %117 to i64
%119 = mul i64 %118, 4
store i64 %119, i64* %16
%120 = load i32, i32* %6
%121 = zext i32 %120 to i64
%122 = mul i64 %121, 4
store i64 %122, i64* %17
%123 = load i32, i32* %6
%124 = zext i32 %123 to i64
%125 = mul i64 %124, 4
store i64 %125, i64* %18
%126 = load i32, i32* %6
%127 = load i32, i32* %6
%128 = mul i32 %126, %127
%129 = zext i32 %128 to i64
%130 = mul i64 %129, 4
%131 = trunc i64 %130 to i32
%132 = call i64 @malloc(i32 %131)
%133 = inttoptr i64 %132 to float*
store float* %133, float** %19
%134 = load i32, i32* %6
%135 = zext i32 %134 to i64
%136 = mul i64 %135, 4
%137 = trunc i64 %136 to i32
%138 = call i64 @malloc(i32 %137)
%139 = inttoptr i64 %138 to float*
store float* %139, float** %20
%140 = load i32, i32* %6
%141 = zext i32 %140 to i64
%142 = mul i64 %141, 4
%143 = trunc i64 %142 to i32
%144 = call i64 @malloc(i32 %143)
%145 = inttoptr i64 %144 to float*
store float* %145, float** %21
%146 = load float*, float** %19
%147 = load float*, float** %20
%148 = load float*, float** %21
%149 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), float* %146, float* %147, float* %148)
store i32 0, i32* %2
br label %150
150: ; preds = %178, %104
%151 = load i32, i32* %2
%152 = load i32, i32* %6
%153 = icmp ult i32 %151, %152
br i1 %153, label %154, label %181
154: ; preds = %150
store i32 0, i32* %3
br label %155
155: ; preds = %174, %154
%156 = load i32, i32* %3
%157 = load i32, i32* %6
%158 = icmp ult i32 %156, %157
br i1 %158, label %159, label %177
159: ; preds = %155
%160 = load i32, i32* %2
%161 = sitofp i32 %160 to float
%162 = fmul float 0x3FF19999A0000000, %161
%163 = load i32, i32* %3
%164 = sitofp i32 %163 to float
%165 = fmul float %162, %164
%166 = load float*, float** %19
%167 = load i32, i32* %2
%168 = load i32, i32* %6
%169 = mul i32 %167, %168
%170 = load i32, i32* %3
%171 = add i32 %169, %170
%172 = zext i32 %171 to i64
%173 = getelementptr inbounds float, float* %166, i64 %172
store float %165, float* %173
br label %174
174: ; preds = %159
%175 = load i32, i32* %3
%176 = add nsw i32 %175, 1
store i32 %176, i32* %3
br label %155
177: ; preds = %155
br label %178
178: ; preds = %177
%179 = load i32, i32* %2
%180 = add nsw i32 %179, 1
store i32 %180, i32* %2
br label %150
181: ; preds = %150
store i32 0, i32* %2
br label %182
182: ; preds = %194, %181
%183 = load i32, i32* %2
%184 = load i32, i32* %6
%185 = icmp ult i32 %183, %184
br i1 %185, label %186, label %197
186: ; preds = %182
%187 = load i32, i32* %2
%188 = sitofp i32 %187 to float
%189 = fmul float 0x40019999A0000000, %188
%190 = load float*, float** %20
%191 = load i32, i32* %2
%192 = sext i32 %191 to i64
%193 = getelementptr inbounds float, float* %190, i64 %192
store float %189, float* %193
br label %194
194: ; preds = %186
%195 = load i32, i32* %2
%196 = add nsw i32 %195, 1
store i32 %196, i32* %2
br label %182
197: ; preds = %182
store i32 0, i32* %2
br label %198
198: ; preds = %207, %197
%199 = load i32, i32* %2
%200 = load i32, i32* %6
%201 = icmp ult i32 %199, %200
br i1 %201, label %202, label %210
202: ; preds = %198
%203 = load float*, float** %21
%204 = load i32, i32* %2
%205 = sext i32 %204 to i64
%206 = getelementptr inbounds float, float* %203, i64 %205
store float 0.000000e+00, float* %206
br label %207
207: ; preds = %202
%208 = load i32, i32* %2
%209 = add nsw i32 %208, 1
store i32 %209, i32* %2
br label %198
210: ; preds = %198
%211 = load i32, i32* %14
%212 = load i32, i32* @CL_MEM_USE_HOST_PTR
%213 = load i64, i64* %16
%214 = load float*, float** %19
%215 = call i32 @clCreateBuffer(i32 %211, i32 %212, i64 %213, float* %214, i32* %4)
store i32 %215, i32* %22
%216 = load i32, i32* %14
%217 = load i32, i32* @CL_MEM_USE_HOST_PTR
%218 = load i64, i64* %17
%219 = load float*, float** %20
%220 = call i32 @clCreateBuffer(i32 %216, i32 %217, i64 %218, float* %219, i32* %4)
store i32 %220, i32* %23
%221 = load i32, i32* %14
%222 = load i32, i32* @CL_MEM_USE_HOST_PTR
%223 = load i64, i64* %18
%224 = load float*, float** %21
%225 = call i32 @clCreateBuffer(i32 %221, i32 %222, i64 %223, float* %224, i32* %4)
store i32 %225, i32* %24
%226 = bitcast [229 x i8]* %25 to i8*
%227 = getelementptr inbounds [1 x i8*], [1 x i8*]* %26, i64 0, i64 0
%228 = getelementptr inbounds [229 x i8], [229 x i8]* %25, i64 0, i64 0
store i8* %228, i8** %227
store i64 229, i64* %27
%229 = load i32, i32* %14
%230 = bitcast [1 x i8*]* %26 to i8**
%231 = call i32 @clCreateProgramWithSource(i32 %229, i32 1, i8** %230, i64* %27, i32* %4)
store i32 %231, i32* %28
%232 = load i32, i32* %28
%233 = call i32 @clBuildProgram(i32 %232, i32 1, i32* %12, i32 0, i32 0, i32 0)
%234 = load i32, i32* %28
%235 = call i32 @clCreateKernel(i32 %234, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i32* %4)
store i32 %235, i32* %29
%236 = load i32, i32* %29
%237 = call i32 @clSetKernelArg(i32 %236, i32 0, i32 4, i32* %6)
%238 = load i32, i32* %29
%239 = call i32 @clSetKernelArg(i32 %238, i32 1, i32 4, i32* %22)
%240 = load i32, i32* %29
%241 = call i32 @clSetKernelArg(i32 %240, i32 2, i32 4, i32* %23)
%242 = load i32, i32* %29
%243 = call i32 @clSetKernelArg(i32 %242, i32 3, i32 4, i32* %24)
%244 = getelementptr inbounds [1 x i64], [1 x i64]* %30, i64 0, i64 0
%245 = load i32, i32* %6
%246 = zext i32 %245 to i64
store i64 %246, i64* %244
%247 = bitcast [1 x i64]* %31 to i8*
%248 = load i32, i32* %15
%249 = load i32, i32* %29
%250 = getelementptr inbounds [1 x i64], [1 x i64]* %30, i64 0, i64 0
%251 = getelementptr inbounds [1 x i64], [1 x i64]* %31, i64 0, i64 0
%252 = getelementptr inbounds [10 x i32], [10 x i32]* %32, i64 0, i64 0
%253 = call i32 @clEnqueueNDRangeKernel(i32 %248, i32 %249, i32 1, i32 0, i64* %250, i64* %251, i32 0, i32 0, i32* %252)
%254 = load i32, i32* %15
%255 = load i32, i32* %24
%256 = load i32, i32* @CL_TRUE
%257 = load i64, i64* %18
%258 = load float*, float** %21
%259 = getelementptr inbounds [10 x i32], [10 x i32]* %32, i64 0, i64 1
%260 = call i32 @clEnqueueReadBuffer(i32 %254, i32 %255, i32 %256, i32 0, i64 %257, float* %258, i32 0, i32 0, i32* %259)
%261 = getelementptr inbounds [10 x i32], [10 x i32]* %32, i64 0, i64 0
%262 = call i32 @clWaitForEvents(i32 2, i32* %261)
store i32 %262, i32* %4
store i32 0, i32* %2
br label %263
263: ; preds = %276, %210
%264 = load i32, i32* %2
%265 = load i32, i32* %6
%266 = icmp ult i32 %264, %265
br i1 %266, label %267, label %279
267: ; preds = %263
%268 = load i32, i32* %2
%269 = load float*, float** %21
%270 = load i32, i32* %2
%271 = sext i32 %270 to i64
%272 = getelementptr inbounds float, float* %269, i64 %271
%273 = load float, float* %272
%274 = fpext float %273 to double
%275 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i64 0, i64 0), i32 %268, double %274)
br label %276
276: ; preds = %267
%277 = load i32, i32* %2
%278 = add nsw i32 %277, 1
store i32 %278, i32* %2
br label %263
279: ; preds = %263
%280 = load i32, i32* %4
%281 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.4, i64 0, i64 0), i32 %280)
%282 = getelementptr inbounds [10 x i32], [10 x i32]* %32, i64 0, i64 1
%283 = load i32, i32* %282
%284 = call i32 @clReleaseEvent(i32 %283)
%285 = getelementptr inbounds [10 x i32], [10 x i32]* %32, i64 0, i64 0
%286 = load i32, i32* %285
%287 = call i32 @clReleaseEvent(i32 %286)
%288 = load i32, i32* %29
%289 = call i32 @clReleaseKernel(i32 %288)
%290 = load i32, i32* %28
%291 = call i32 @clReleaseProgram(i32 %290)
%292 = load i32, i32* %22
%293 = call i32 @clReleaseMemObject(i32 %292)
%294 = load i32, i32* %23
%295 = call i32 @clReleaseMemObject(i32 %294)
%296 = load i32, i32* %24
%297 = call i32 @clReleaseMemObject(i32 %296)
%298 = load i32, i32* %15
%299 = call i32 @clReleaseCommandQueue(i32 %298)
%300 = load i32, i32* %14
%301 = call i32 @clReleaseContext(i32 %300)
%302 = load float*, float** %19
%303 = call i32 @free(float* %302)
%304 = load float*, float** %20
%305 = call i32 @free(float* %304)
%306 = load float*, float** %21
%307 = call i32 @free(float* %306)
%308 = load i32, i32* %1
ret i32 %308
}

LLVM IR (-O2):
@CL_PLATFORM_NAME = global i32 0
@CL_DEVICE_TYPE_CPU = global i32 0
@CL_CONTEXT_PLATFORM = global i32 0
@.str.1 = [21 x i8] c"XXX aa b c %p %p %p\0A\00"
@CL_MEM_USE_HOST_PTR = global i32 0
@__const.main.kernel_code = [229 x i8] c"__kernel void matvecmult_kern(\0A uint n,__global float* aa,__global float* b,__global float* c )\0A{\0A int i = get_global_id(0);\0A int j;\0A float tmp = 0.0f;\0A for(j=0;j<n;j++) tmp += aa[i*n+j] * b[j];\0A c[i] = aa[i*n+i];\0A}\0A\00"
@.str.2 = [16 x i8] c"matvecmult_kern\00"
@CL_TRUE = global i32 0
@.str.3 = [10 x i8] c"c[%d] %f\0A\00"
@.str.4 = [29 x i8] c"clWaitForEvents returned %d\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [256 x i8]
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca [3 x i32]
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca [229 x i8]
%12 = alloca [1 x i8*]
%13 = alloca i64
%14 = alloca [1 x i64]
%15 = alloca [1 x i64]
%16 = alloca [10 x i32]
%17 = bitcast i32* %1 to i8*
%18 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%19 = bitcast i32* %3 to i8*
store i32 1024, i32* %3
%20 = bitcast i32* %4 to i8*
%21 = call i32 @clGetPlatformIDs(i32 0, i32* null, i32* %4)
%22 = load i32, i32* %4
%23 = shl i32 %22, 2
%24 = call i64 @malloc(i32 %23)
%25 = inttoptr i64 %24 to i32*
%26 = load i32, i32* %4
%27 = call i32 @clGetPlatformIDs(i32 %26, i32* %25, i32* null)
%28 = load i32, i32* %4
%29 = icmp sgt i32 %28, 0
br i1 %29, label %30, label %51
30: ; preds = %0
%31 = bitcast [256 x i8]* %2 to i64*
br label %32
32: ; preds = %30, %42
%33 = phi i64 [ 0, %30 ], [ %43, %42 ]
%34 = getelementptr inbounds i32, i32* %25, i64 %33
%35 = load i32, i32* %34
%36 = load i32, i32* @CL_PLATFORM_NAME
%37 = call i32 @clGetPlatformInfo(i32 %35, i32 %36, i32 256, i8* %18, i32 0)
%38 = load i64, i64* %31
%39 = icmp eq i64 %38, 32202996690480995
br i1 %39, label %40, label %42
40: ; preds = %32
%41 = load i32, i32* %4
br label %47
42: ; preds = %32
%43 = add nuw nsw i64 %33, 1
%44 = load i32, i32* %4
%45 = sext i32 %44 to i64
%46 = icmp slt i64 %43, %45
br i1 %46, label %32, label %47
47: ; preds = %42, %40
%48 = phi i32 [ %41, %40 ], [ %44, %42 ]
%49 = phi i64 [ %33, %40 ], [ %43, %42 ]
%50 = trunc i64 %49 to i32
br label %51
51: ; preds = %47, %0
%52 = phi i32 [ %28, %0 ], [ %48, %47 ]
%53 = phi i32 [ 0, %0 ], [ %50, %47 ]
%54 = icmp slt i32 %53, %52
br i1 %54, label %55, label %72
55: ; preds = %51
%56 = zext i32 %53 to i64
%57 = getelementptr inbounds i32, i32* %25, i64 %56
%58 = load i32, i32* %57
%59 = bitcast i32* %5 to i8*
%60 = bitcast i32* %6 to i8*
%61 = load i32, i32* @CL_DEVICE_TYPE_CPU
%62 = call i32 @clGetDeviceIDs(i32 %58, i32 %61, i32 0, i32* null, i32* %5)
%63 = load i32, i32* %5
%64 = shl i32 %63, 2
%65 = call i64 @malloc(i32 %64)
%66 = inttoptr i64 %65 to i32*
%67 = load i32, i32* @CL_DEVICE_TYPE_CPU
%68 = load i32, i32* %5
%69 = call i32 @clGetDeviceIDs(i32 %58, i32 %67, i32 %68, i32* %66, i32* null)
%70 = load i32, i32* %5
%71 = icmp eq i32 %70, 0
br i1 %71, label %92, label %74
72: ; preds = %51
%73 = call i32 @exit(i32 1)
unreachable
74: ; preds = %55
%75 = load i32, i32* %66
store i32 %75, i32* %6
%76 = bitcast [3 x i32]* %7 to i8*
%77 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 0
%78 = load i32, i32* @CL_CONTEXT_PLATFORM
store i32 %78, i32* %77
%79 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 1
store i32 %58, i32* %79
%80 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 2
store i32 0, i32* %80
%81 = call i32 @clCreateContext(i32* %77, i32 1, i32* %6, i32 0, i32 0, i32* %1)
%82 = load i32, i32* %6
%83 = call i32 @clCreateCommandQueue(i32 %81, i32 %82, i32 0, i32* %1)
%84 = call i64 @malloc(i32 4194304)
%85 = inttoptr i64 %84 to float*
%86 = call i64 @malloc(i32 4096)
%87 = inttoptr i64 %86 to float*
%88 = call i64 @malloc(i32 4096)
%89 = inttoptr i64 %88 to float*
%90 = inttoptr i64 %88 to i8*
%91 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), float* %85, float* %87, float* %89)
br label %94
92: ; preds = %55
%93 = call i32 @exit(i32 1)
unreachable
94: ; preds = %74, %129
%95 = phi i32 [ %130, %129 ], [ 0, %74 ]
%96 = sitofp i32 %95 to float
%97 = fmul float %96, 0x3FF19999A0000000
%98 = shl i32 %95, 10
%99 = insertelement <4 x float> poison, float %97, i64 0
%100 = shufflevector <4 x float> %99, <4 x float> poison, <4 x i32> zeroinitializer
%101 = insertelement <4 x float> poison, float %97, i64 0
%102 = shufflevector <4 x float> %101, <4 x float> poison, <4 x i32> zeroinitializer
br label %103
103: ; preds = %103, %94
%104 = phi i64 [ 0, %94 ], [ %127, %103 ]
%105 = trunc i64 %104 to i32
%106 = or i32 %105, 1
%107 = insertelement <2 x i32> poison, i32 %105, i64 0
%108 = shufflevector <2 x i32> %107, <2 x i32> poison, <2 x i32> zeroinitializer
%109 = or <2 x i32> %108, <i32 2, i32 3>
%110 = insertelement <4 x i32> poison, i32 %105, i64 0
%111 = insertelement <4 x i32> %110, i32 %106, i64 1
%112 = shufflevector <2 x i32> %109, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%113 = shufflevector <4 x i32> %111, <4 x i32> %112, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
%114 = insertelement <4 x i32> poison, i32 %105, i64 0
%115 = shufflevector <4 x i32> %114, <4 x i32> poison, <4 x i32> zeroinitializer
%116 = or <4 x i32> %115, <i32 4, i32 5, i32 6, i32 7>
%117 = sitofp <4 x i32> %113 to <4 x float>
%118 = sitofp <4 x i32> %116 to <4 x float>
%119 = fmul <4 x float> %100, %117
%120 = fmul <4 x float> %102, %118
%121 = add i32 %98, %105
%122 = zext i32 %121 to i64
%123 = getelementptr inbounds float, float* %85, i64 %122
%124 = bitcast float* %123 to <4 x float>*
store <4 x float> %119, <4 x float>* %124
%125 = getelementptr inbounds float, float* %123, i64 4
%126 = bitcast float* %125 to <4 x float>*
store <4 x float> %120, <4 x float>* %126
%127 = add nuw i64 %104, 8
%128 = icmp eq i64 %127, 1024
br i1 %128, label %129, label %103
129: ; preds = %103
%130 = add nuw nsw i32 %95, 1
%131 = icmp eq i32 %130, 1024
br i1 %131, label %132, label %94
132: ; preds = %129, %132
%133 = phi i64 [ %155, %132 ], [ 0, %129 ]
%134 = phi <4 x i32> [ %156, %132 ], [ <i32 0, i32 1, i32 2, i32 3>, %129 ]
%135 = add <4 x i32> %134, <i32 4, i32 4, i32 4, i32 4>
%136 = sitofp <4 x i32> %134 to <4 x float>
%137 = sitofp <4 x i32> %135 to <4 x float>
%138 = fmul <4 x float> %136, <float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000>
%139 = fmul <4 x float> %137, <float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000>
%140 = getelementptr inbounds float, float* %87, i64 %133
%141 = bitcast float* %140 to <4 x float>*
store <4 x float> %138, <4 x float>* %141
%142 = getelementptr inbounds float, float* %140, i64 4
%143 = bitcast float* %142 to <4 x float>*
store <4 x float> %139, <4 x float>* %143
%144 = or i64 %133, 8
%145 = add <4 x i32> %134, <i32 8, i32 8, i32 8, i32 8>
%146 = add <4 x i32> %134, <i32 12, i32 12, i32 12, i32 12>
%147 = sitofp <4 x i32> %145 to <4 x float>
%148 = sitofp <4 x i32> %146 to <4 x float>
%149 = fmul <4 x float> %147, <float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000>
%150 = fmul <4 x float> %148, <float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000, float 0x40019999A0000000>
%151 = getelementptr inbounds float, float* %87, i64 %144
%152 = bitcast float* %151 to <4 x float>*
store <4 x float> %149, <4 x float>* %152
%153 = getelementptr inbounds float, float* %151, i64 4
%154 = bitcast float* %153 to <4 x float>*
store <4 x float> %150, <4 x float>* %154
%155 = add nuw nsw i64 %133, 16
%156 = add <4 x i32> %134, <i32 16, i32 16, i32 16, i32 16>
%157 = icmp eq i64 %155, 1024
br i1 %157, label %158, label %132
158: ; preds = %132
%159 = bitcast i32* %8 to i8*
%160 = load i32, i32* @CL_MEM_USE_HOST_PTR
%161 = call i32 @clCreateBuffer(i32 %81, i32 %160, i64 4194304, float* %85, i32* %1)
store i32 %161, i32* %8
%162 = bitcast i32* %9 to i8*
%163 = load i32, i32* @CL_MEM_USE_HOST_PTR
%164 = call i32 @clCreateBuffer(i32 %81, i32 %163, i64 4096, float* %87, i32* %1)
store i32 %164, i32* %9
%165 = bitcast i32* %10 to i8*
%166 = load i32, i32* @CL_MEM_USE_HOST_PTR
%167 = call i32 @clCreateBuffer(i32 %81, i32 %166, i64 4096, float* %89, i32* %1)
store i32 %167, i32* %10
%168 = getelementptr inbounds [229 x i8], [229 x i8]* %11, i64 0, i64 0
%169 = bitcast [1 x i8*]* %12 to i8*
%170 = getelementptr inbounds [1 x i8*], [1 x i8*]* %12, i64 0, i64 0
store i8* %168, i8** %170
%171 = bitcast i64* %13 to i8*
store i64 229, i64* %13
%172 = call i32 @clCreateProgramWithSource(i32 %81, i32 1, i8** %170, i64* %13, i32* %1)
%173 = call i32 @clBuildProgram(i32 %172, i32 1, i32* %6, i32 0, i32 0, i32 0)
%174 = call i32 @clCreateKernel(i32 %172, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i32* %1)
%175 = call i32 @clSetKernelArg(i32 %174, i32 0, i32 4, i32* %3)
%176 = call i32 @clSetKernelArg(i32 %174, i32 1, i32 4, i32* %8)
%177 = call i32 @clSetKernelArg(i32 %174, i32 2, i32 4, i32* %9)
%178 = call i32 @clSetKernelArg(i32 %174, i32 3, i32 4, i32* %10)
%179 = bitcast [1 x i64]* %14 to i8*
%180 = getelementptr inbounds [1 x i64], [1 x i64]* %14, i64 0, i64 0
%181 = load i32, i32* %3
%182 = zext i32 %181 to i64
store i64 %182, i64* %180
%183 = bitcast [1 x i64]* %15 to i8*
%184 = getelementptr inbounds [1 x i64], [1 x i64]* %15, i64 0, i64 0
store i64 16, i64* %184
%185 = bitcast [10 x i32]* %16 to i8*
%186 = getelementptr inbounds [10 x i32], [10 x i32]* %16, i64 0, i64 0
%187 = call i32 @clEnqueueNDRangeKernel(i32 %83, i32 %174, i32 1, i32 0, i64* %180, i64* %184, i32 0, i32 0, i32* %186)
%188 = load i32, i32* %10
%189 = load i32, i32* @CL_TRUE
%190 = getelementptr inbounds [10 x i32], [10 x i32]* %16, i64 0, i64 1
%191 = call i32 @clEnqueueReadBuffer(i32 %83, i32 %188, i32 %189, i32 0, i64 4096, float* %89, i32 0, i32 0, i32* %190)
%192 = call i32 @clWaitForEvents(i32 2, i32* %186)
store i32 %192, i32* %1
%193 = load i32, i32* %3
%194 = icmp eq i32 %193, 0
br i1 %194, label %208, label %195
195: ; preds = %158, %195
%196 = phi i64 [ %202, %195 ], [ 0, %158 ]
%197 = getelementptr inbounds float, float* %89, i64 %196
%198 = load float, float* %197
%199 = fpext float %198 to double
%200 = trunc i64 %196 to i32
%201 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i64 0, i64 0), i32 %200, double %199)
%202 = add nuw nsw i64 %196, 1
%203 = load i32, i32* %3
%204 = zext i32 %203 to i64
%205 = icmp ult i64 %202, %204
br i1 %205, label %195, label %206
206: ; preds = %195
%207 = load i32, i32* %1
br label %208
208: ; preds = %206, %158
%209 = phi i32 [ %207, %206 ], [ %192, %158 ]
%210 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([29 x i8], [29 x i8]* @.str.4, i64 0, i64 0), i32 %209)
%211 = load i32, i32* %190
%212 = call i32 @clReleaseEvent(i32 %211)
%213 = load i32, i32* %186
%214 = call i32 @clReleaseEvent(i32 %213)
%215 = call i32 @clReleaseKernel(i32 %174)
%216 = call i32 @clReleaseProgram(i32 %172)
%217 = load i32, i32* %8
%218 = call i32 @clReleaseMemObject(i32 %217)
%219 = load i32, i32* %9
%220 = call i32 @clReleaseMemObject(i32 %219)
%221 = load i32, i32* %10
%222 = call i32 @clReleaseMemObject(i32 %221)
%223 = call i32 @clReleaseCommandQueue(i32 %83)
%224 = call i32 @clReleaseContext(i32 %81)
%225 = call i32 @free(float* %85)
%226 = call i32 @free(float* %87)
%227 = call i32 @free(float* %89)
ret i32 0
}