#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 scalar_t__ cl_uint;
typedef int /*<<< orphan*/ cl_program;
typedef int /*<<< orphan*/ cl_platform_id;
typedef int cl_mem;
typedef int /*<<< orphan*/ cl_kernel;
typedef int /*<<< orphan*/ *cl_device_id;
typedef int /*<<< orphan*/ cl_context;
typedef int /*<<< orphan*/ cl_command_queue;

/* Variables and functions */
int /*<<< orphan*/ CL_DEVICE_TYPE_DEFAULT;
int /*<<< orphan*/ CL_MEM_READ_WRITE;
int CL_SUCCESS;
int /*<<< orphan*/ CL_TRUE;
int EXIT_FAILURE;
int /*<<< orphan*/ check_error(int, char *, char *, int);
int clBuildProgram(int /*<<< orphan*/, int /*<<< orphan*/, int /*<<< orphan*/ *,
                   int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                   int /*<<< orphan*/ *);
int clCreateBuffer(int /*<<< orphan*/, int /*<<< orphan*/, int,
                   int /*<<< orphan*/ *, 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 **,
                                             int /*<<< orphan*/ *, int *);
int clEnqueueNDRangeKernel(int /*<<< orphan*/, int /*<<< orphan*/, int,
                           int /*<<< orphan*/ *, size_t const *, size_t const *,
                           int /*<<< orphan*/, int /*<<< orphan*/ *,
                           int /*<<< orphan*/ *);
int clEnqueueReadBuffer(int /*<<< orphan*/, int, int /*<<< orphan*/,
                        int /*<<< orphan*/, int, float *, int /*<<< orphan*/,
                        int /*<<< orphan*/ *, int /*<<< orphan*/ *);
int clEnqueueWriteBuffer(int /*<<< orphan*/, int, int /*<<< orphan*/,
                         int /*<<< orphan*/, int, float *, int /*<<< orphan*/,
                         int /*<<< orphan*/ *, int /*<<< orphan*/ *);
int clFinish(int /*<<< orphan*/);
int clGetDeviceIDs(int /*<<< orphan*/, int /*<<< orphan*/, int,
                   int /*<<< orphan*/ **, int /*<<< orphan*/ *);
int clGetPlatformIDs(scalar_t__, int /*<<< orphan*/ *, scalar_t__ *);
int /*<<< orphan*/ clReleaseCommandQueue(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseContext(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseKernel(int /*<<< orphan*/);
int /*<<< orphan*/ clReleaseMemObject(int);
int /*<<< orphan*/ clReleaseProgram(int /*<<< orphan*/);
int clSetKernelArg(int /*<<< orphan*/, int, int, int *);
int /*<<< orphan*/ free(float *);
char *getKernelSource(char *);
float *malloc(int);
int /*<<< orphan*/ printf(char *, ...);
double wtime();
int main(int argc, char *argv[]) {
  int err;
  unsigned int correct;
  float *h_in = malloc(64 * sizeof(float));
  float *h_out = malloc(64 * sizeof(float));
  int h_clock = 0;
  cl_device_id device_id;
  cl_context context;
  cl_command_queue command_queue;
  cl_program program;
  cl_kernel ko_MatMul;
  cl_mem d_in;
  cl_mem d_out;
  cl_mem d_clock;
  cl_uint num_platforms;
  err = clGetPlatformIDs(0, NULL, &num_platforms);
  check_error(err, "Finding platforms",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              205);
  if (num_platforms == 0) {
    printf("Found 0 platforms\n");
    return EXIT_FAILURE;
  }
  cl_platform_id platform[num_platforms];
  err = clGetPlatformIDs(num_platforms, platform, NULL);
  check_error(err, "Getting platforms's IDs",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              218);
  for (int i = 0; i < num_platforms; ++i) {
    err = clGetDeviceIDs(platform[i], CL_DEVICE_TYPE_DEFAULT, 1, &device_id,
                         NULL);
    if (err == CL_SUCCESS) {
      break;
    }
  }
  if (device_id == NULL) {
    printf("No devices found\n");
  }
  context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
  check_error(err, "Creating context",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              260);
  command_queue = clCreateCommandQueue(context, device_id, 0, &err);
  check_error(err, "Creating command queue",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              275);
  char *gemm_kernel = getKernelSource("ds_read_b32.cl");
  program = clCreateProgramWithSource(context, 1, (const char **)&gemm_kernel,
                                      NULL, &err);
  check_error(err, "Creating program from source",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              296);
  err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
  check_error(err, "Build program",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              315);
  ko_MatMul = clCreateKernel(program, "microbench", &err);
  check_error(err, "Creating kernel",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              329);
  d_in = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * 64, NULL,
                        &err);
  check_error(err, "Creating buffer d_in",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              350);
  d_out = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * 64, NULL,
                         &err);
  check_error(err, "Creating buffer d_out",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              357);
  err = clEnqueueWriteBuffer(command_queue, d_in, CL_TRUE, 0,
                             sizeof(float) * 64, h_in, 0, NULL, NULL);
  check_error(err, "Copying h_in to d_in",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              383);
  err = clSetKernelArg(ko_MatMul, 0, sizeof(cl_mem), &d_in);
  err |= clSetKernelArg(ko_MatMul, 1, sizeof(cl_mem), &d_out);
  err |= clSetKernelArg(ko_MatMul, 2, sizeof(int), &h_clock);
  check_error(err, "Setting kernel arguments",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              408);
  const size_t global[2] = {8, 8};
  const size_t local[2] = {8, 8};
  double rtime = wtime();
  for (int i = 0; i < 5; ++i) {
    err = clEnqueueNDRangeKernel(command_queue, ko_MatMul, 2, NULL, global,
                                 local, 0, NULL, NULL);
    err = clFinish(command_queue);
  }
  rtime = (wtime() - rtime) / (double)5;
  check_error(err, "Waiting for kernel to finish",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              456);
  err = clEnqueueReadBuffer(command_queue, d_out, CL_TRUE, 0,
                            sizeof(float) * 64, h_out, 0, NULL, NULL);
  check_error(err, "Copying d_out to h_out",
              "/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/"
              "2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/"
              "LearnOpenCLFromScratch/dgemm/bench/bench.c",
              481);
  if (err != CL_SUCCESS) {
    printf("Error: Failed to read output array\n");
  }
  printf("\n");
  correct = 0;
  float temp = 0;
  for (int i = 0; i < 64; ++i) {
    printf("out[%d] = %f\n", i, h_out[i]);
  }
  clReleaseMemObject(d_in);
  clReleaseMemObject(d_out);
  clReleaseMemObject(d_clock);
  clReleaseContext(context);
  clReleaseCommandQueue(command_queue);
  clReleaseProgram(program);
  clReleaseKernel(ko_MatMul);
  free(h_in);
  free(h_out);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    $0x100,%edi
call   1130 <malloc@plt>
mov    %rax,-0x20(%rbp)
mov    $0x100,%edi
call   1130 <malloc@plt>
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
xor    %eax,%eax
mov    %eax,%esi
lea    -0x60(%rbp),%rdx
mov    %rsi,%rdi
call   10d0 <clGetPlatformIDs@plt>
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xd2f(%rip),%rsi
lea    0xd3a(%rip),%rdx
mov    $0xcd,%ecx
call   1110 <check_error@plt>
cmpq   $0x0,-0x60(%rbp)
jne    1314 <main+0x94>
lea    0xdc7(%rip),%rdi
mov    $0x0,%al
call   10e0 <printf@plt>
mov    0x2cbe(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    1898 <main+0x618>
mov    -0x60(%rbp),%rax
mov    %rsp,%rcx
mov    %rcx,-0x68(%rbp)
lea    0xf(,%rax,4),%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rsi
sub    %rcx,%rsi
mov    %rsi,-0xc0(%rbp)
mov    %rsi,%rsp
mov    %rax,-0x70(%rbp)
mov    -0x60(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%edx
call   10d0 <clGetPlatformIDs@plt>
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xd7d(%rip),%rsi
lea    0xcba(%rip),%rdx
mov    $0xda,%ecx
call   1110 <check_error@plt>
movl   $0x0,-0x74(%rbp)
movslq -0x74(%rbp),%rax
cmp    -0x60(%rbp),%rax
jge    13d6 <main+0x156>
mov    -0xc0(%rbp),%rax
movslq -0x74(%rbp),%rcx
mov    (%rax,%rcx,4),%edi
mov    0x2c3c(%rip),%rax
mov    (%rax),%esi
mov    $0x1,%edx
lea    -0x38(%rbp),%rcx
xor    %eax,%eax
mov    %eax,%r8d
call   10a0 <clGetDeviceIDs@plt>
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    0x2c0a(%rip),%rcx
cmp    (%rcx),%eax
jne    13c3 <main+0x143>
jmp    13d6 <main+0x156>
jmp    13c8 <main+0x148>
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    1371 <main+0xf1>
cmpq   $0x0,-0x38(%rbp)
jne    13ef <main+0x16f>
lea    0xd06(%rip),%rdi
mov    $0x0,%al
call   10e0 <printf@plt>
xor    %edi,%edi
mov    $0x1,%esi
lea    -0x38(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%r8d
lea    -0x14(%rbp),%r9
mov    %r8,%rcx
call   1100 <clCreateContext@plt>
mov    %eax,-0x3c(%rbp)
mov    -0x14(%rbp),%edi
lea    0xce8(%rip),%rsi
lea    0xbfb(%rip),%rdx
mov    $0x104,%ecx
call   1110 <check_error@plt>
mov    -0x3c(%rbp),%edi
mov    -0x38(%rbp),%rsi
xor    %edx,%edx
lea    -0x14(%rbp),%rcx
call   10c0 <clCreateCommandQueue@plt>
mov    %eax,-0x40(%rbp)
mov    -0x14(%rbp),%edi
lea    0xcc9(%rip),%rsi
lea    0xbcb(%rip),%rdx
mov    $0x113,%ecx
call   1110 <check_error@plt>
lea    0xcc8(%rip),%rdi
call   1180 <getKernelSource@plt>
mov    %rax,-0x80(%rbp)
mov    -0x3c(%rbp),%edi
mov    $0x1,%esi
lea    -0x80(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%ecx
lea    -0x14(%rbp),%r8
call   1060 <clCreateProgramWithSource@plt>
mov    %eax,-0x44(%rbp)
mov    -0x14(%rbp),%edi
lea    0xca8(%rip),%rsi
lea    0xb84(%rip),%rdx
mov    $0x128,%ecx
call   1110 <check_error@plt>
mov    -0x44(%rbp),%edi
xor    %esi,%esi
xor    %eax,%eax
mov    %eax,%r9d
mov    %r9,%rdx
mov    %r9,%rcx
mov    %r9,%r8
call   1030 <clBuildProgram@plt>
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xc8f(%rip),%rsi
lea    0xb4e(%rip),%rdx
mov    $0x13b,%ecx
call   1110 <check_error@plt>
mov    -0x44(%rbp),%edi
lea    0xc82(%rip),%rsi
lea    -0x14(%rbp),%rdx
call   1170 <clCreateKernel@plt>
mov    %eax,-0x48(%rbp)
mov    -0x14(%rbp),%edi
lea    0xc77(%rip),%rsi
lea    0xb1d(%rip),%rdx
mov    $0x149,%ecx
call   1110 <check_error@plt>
mov    -0x3c(%rbp),%edi
mov    0x2acf(%rip),%rax
mov    (%rax),%esi
mov    $0x100,%edx
xor    %eax,%eax
mov    %eax,%ecx
lea    -0x14(%rbp),%r8
call   1080 <clCreateBuffer@plt>
mov    %eax,-0x4c(%rbp)
mov    -0x14(%rbp),%edi
lea    0xc4b(%rip),%rsi
lea    0xae1(%rip),%rdx
mov    $0x15e,%ecx
call   1110 <check_error@plt>
mov    -0x3c(%rbp),%edi
mov    0x2a93(%rip),%rax
mov    (%rax),%esi
mov    $0x100,%edx
xor    %eax,%eax
mov    %eax,%ecx
lea    -0x14(%rbp),%r8
call   1080 <clCreateBuffer@plt>
mov    %eax,-0x50(%rbp)
mov    -0x14(%rbp),%edi
lea    0xc24(%rip),%rsi
lea    0xaa5(%rip),%rdx
mov    $0x165,%ecx
call   1110 <check_error@plt>
mov    -0x40(%rbp),%edi
mov    -0x4c(%rbp),%esi
mov    0x2a5c(%rip),%rax
mov    (%rax),%edx
mov    -0x20(%rbp),%r9
xor    %ecx,%ecx
mov    $0x100,%r8d
xor    %eax,%eax
sub    $0x20,%rsp
movl   $0x0,(%rsp)
movq   $0x0,0x8(%rsp)
movq   $0x0,0x10(%rsp)
call   11a0 <clEnqueueWriteBuffer@plt>
add    $0x20,%rsp
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xbd9(%rip),%rsi
lea    0xa44(%rip),%rdx
mov    $0x17f,%ecx
call   1110 <check_error@plt>
mov    -0x48(%rbp),%edi
xor    %esi,%esi
mov    $0x4,%edx
lea    -0x4c(%rbp),%rcx
call   1190 <clSetKernelArg@plt>
mov    %eax,-0x14(%rbp)
mov    -0x48(%rbp),%edi
mov    $0x1,%esi
mov    $0x4,%edx
lea    -0x50(%rbp),%rcx
call   1190 <clSetKernelArg@plt>
or     -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x48(%rbp),%edi
mov    $0x2,%esi
mov    $0x4,%edx
lea    -0x2c(%rbp),%rcx
call   1190 <clSetKernelArg@plt>
or     -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xb85(%rip),%rsi
lea    0x9db(%rip),%rdx
mov    $0x198,%ecx
call   1110 <check_error@plt>
mov    0xbf0(%rip),%rax
mov    %rax,-0x90(%rbp)
mov    0xbea(%rip),%rax
mov    %rax,-0x88(%rbp)
mov    0xbd4(%rip),%rax
mov    %rax,-0xa0(%rbp)
mov    0xbce(%rip),%rax
mov    %rax,-0x98(%rbp)
mov    $0x0,%al
call   10f0 <wtime@plt>
movsd  %xmm0,-0xa8(%rbp)
ff
movl   $0x0,-0xac(%rbp)
cmpl   $0x5,-0xac(%rbp)
jge    170e <main+0x48e>
mov    -0x40(%rbp),%edi
mov    -0x48(%rbp),%esi
lea    -0x90(%rbp),%r8
lea    -0xa0(%rbp),%r9
mov    $0x2,%edx
xor    %eax,%eax
mov    %eax,%ecx
xor    %eax,%eax
sub    $0x20,%rsp
movl   $0x0,(%rsp)
movq   $0x0,0x8(%rsp)
movq   $0x0,0x10(%rsp)
call   10b0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x14(%rbp)
mov    -0x40(%rbp),%edi
call   1050 <clFinish@plt>
mov    %eax,-0x14(%rbp)
mov    -0xac(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xac(%rbp)
jmp    169a <main+0x41a>
mov    $0x0,%al
call   10f0 <wtime@plt>
subsd  -0xa8(%rbp),%xmm0
ff
movsd  0x8db(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
mov    -0x14(%rbp),%edi
lea    0xa9b(%rip),%rsi
lea    0x8d8(%rip),%rdx
mov    $0x1c8,%ecx
call   1110 <check_error@plt>
mov    -0x40(%rbp),%edi
mov    -0x50(%rbp),%esi
mov    0x288f(%rip),%rax
mov    (%rax),%edx
mov    -0x28(%rbp),%r9
xor    %ecx,%ecx
mov    $0x100,%r8d
xor    %eax,%eax
sub    $0x20,%rsp
movl   $0x0,(%rsp)
movq   $0x0,0x8(%rsp)
movq   $0x0,0x10(%rsp)
call   1140 <clEnqueueReadBuffer@plt>
add    $0x20,%rsp
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edi
lea    0xa57(%rip),%rsi
lea    0x877(%rip),%rdx
mov    $0x1e1,%ecx
call   1110 <check_error@plt>
mov    -0x14(%rbp),%eax
mov    0x2809(%rip),%rcx
cmp    (%rcx),%eax
je     17cd <main+0x54d>
lea    0xa44(%rip),%rdi
mov    $0x0,%al
call   10e0 <printf@plt>
lea    0x92a(%rip),%rdi
mov    $0x0,%al
call   10e0 <printf@plt>
movl   $0x0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0xb0(%rbp)
ff
movl   $0x0,-0xb4(%rbp)
cmpl   $0x40,-0xb4(%rbp)
jge    1840 <main+0x5c0>
mov    -0xb4(%rbp),%esi
mov    -0x28(%rbp),%rax
movslq -0xb4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
lea    0xa09(%rip),%rdi
mov    $0x1,%al
call   10e0 <printf@plt>
mov    -0xb4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xb4(%rbp)
jmp    17f7 <main+0x577>
mov    -0x4c(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x50(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x54(%rbp),%edi
call   1160 <clReleaseMemObject@plt>
mov    -0x3c(%rbp),%edi
call   1150 <clReleaseContext@plt>
mov    -0x40(%rbp),%edi
call   1120 <clReleaseCommandQueue@plt>
mov    -0x44(%rbp),%edi
call   1090 <clReleaseProgram@plt>
mov    -0x48(%rbp),%edi
call   1070 <clReleaseKernel@plt>
mov    -0x20(%rbp),%rdi
call   1040 <free@plt>
mov    -0x28(%rbp),%rdi
call   1040 <free@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x68(%rbp),%rax
mov    %rax,%rsp
mov    -0x4(%rbp),%eax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    $0x100,%edi
call   1150 <malloc@plt>
mov    %rax,%r14
mov    $0x100,%edi
call   1150 <malloc@plt>
mov    %rax,%rbx
movl   $0x0,-0x54(%rbp)
lea    -0x40(%rbp),%rdx
xor    %edi,%edi
xor    %esi,%esi
call   10f0 <clGetPlatformIDs@plt>
mov    %eax,-0x2c(%rbp)
lea    0xd37(%rip),%rsi
lea    0xd42(%rip),%rdx
mov    %eax,%edi
mov    $0xcd,%ecx
call   1130 <check_error@plt>
mov    -0x40(%rbp),%rax
test   %rax,%rax
je     185e <main+0x5be>
mov    %rbx,-0x70(%rbp)
mov    %rsp,-0x68(%rbp)
mov    %rsp,%r12
lea    0xf(,%rax,4),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r12
mov    %r12,%rsp
mov    -0x40(%rbp),%rdi
mov    %r12,%rsi
xor    %edx,%edx
call   10f0 <clGetPlatformIDs@plt>
mov    %eax,-0x2c(%rbp)
lea    0xd9d(%rip),%rsi
lea    0xced(%rip),%rdx
mov    %eax,%edi
mov    $0xda,%ecx
call   1130 <check_error@plt>
cmpq   $0x0,-0x40(%rbp)
mov    %r14,-0x60(%rbp)
jle    13b5 <main+0x115>
mov    $0x1,%ebx
mov    0x2c68(%rip),%r15
lea    -0x48(%rbp),%r14
mov    0x2c4d(%rip),%r13
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    -0x4(%r12,%rbx,4),%edi
mov    (%r15),%esi
mov    $0x1,%edx
mov    %r14,%rcx
xor    %r8d,%r8d
call   10c0 <clGetDeviceIDs@plt>
mov    %eax,-0x2c(%rbp)
cmp    0x0(%r13),%eax
je     13ae <main+0x10e>
lea    0x1(%rbx),%rax
cmp    %rbx,-0x40(%rbp)
mov    %rax,%rbx
jg     1380 <main+0xe0>
cmpq   $0x0,-0x48(%rbp)
jne    13c1 <main+0x121>
lea    0xe72(%rip),%rdi
call   1080 <puts@plt>
lea    -0x48(%rbp),%rdx
lea    -0x2c(%rbp),%r15
xor    %edi,%edi
mov    $0x1,%esi
xor    %ecx,%ecx
xor    %r8d,%r8d
mov    %r15,%r9
call   1120 <clCreateContext@plt>
mov    %eax,%r13d
mov    -0x2c(%rbp),%edi
lea    0xd09(%rip),%rsi
lea    0xc41(%rip),%r14
mov    %r14,%rdx
mov    $0x104,%ecx
call   1130 <check_error@plt>
mov    -0x48(%rbp),%rsi
mov    %r13d,%edi
xor    %edx,%edx
mov    %r15,%rcx
call   10e0 <clCreateCommandQueue@plt>
mov    %eax,%r12d
mov    -0x2c(%rbp),%edi
lea    0xce8(%rip),%rsi
mov    %r14,%rdx
mov    $0x113,%ecx
call   1130 <check_error@plt>
lea    0xceb(%rip),%rdi
call   11a0 <getKernelSource@plt>
mov    %rax,-0x78(%rbp)
lea    -0x78(%rbp),%rdx
mov    %r13d,%edi
mov    $0x1,%esi
xor    %ecx,%ecx
mov    %r15,%r8
call   1070 <clCreateProgramWithSource@plt>
mov    %eax,%ebx
mov    -0x2c(%rbp),%edi
lea    0xccf(%rip),%rsi
mov    %r14,%rdx
mov    $0x128,%ecx
call   1130 <check_error@plt>
mov    %ebx,%edi
xor    %esi,%esi
xor    %edx,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
xor    %r9d,%r9d
call   1030 <clBuildProgram@plt>
mov    %eax,-0x2c(%rbp)
lea    0xcc2(%rip),%rsi
mov    %eax,%edi
mov    %r14,%rdx
mov    $0x13b,%ecx
call   1130 <check_error@plt>
lea    0xcba(%rip),%rsi
mov    %ebx,-0x4c(%rbp)
mov    %ebx,%edi
mov    %r15,%rbx
mov    %r15,%rdx
call   1190 <clCreateKernel@plt>
mov    %eax,%r15d
mov    -0x2c(%rbp),%edi
lea    0xca8(%rip),%rsi
mov    %r14,%rdx
mov    $0x149,%ecx
call   1130 <check_error@plt>
mov    0x2b14(%rip),%rax
mov    (%rax),%esi
mov    %r13d,%edi
mov    $0x100,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
call   10a0 <clCreateBuffer@plt>
mov    %eax,%ebx
mov    %eax,-0x34(%rbp)
mov    -0x2c(%rbp),%edi
lea    0xc81(%rip),%rsi
mov    %r14,%rdx
mov    $0x15e,%ecx
call   1130 <check_error@plt>
mov    0x2add(%rip),%rax
mov    (%rax),%esi
mov    %r13d,-0x50(%rbp)
mov    %r13d,%edi
mov    $0x100,%edx
xor    %ecx,%ecx
lea    -0x2c(%rbp),%r8
call   10a0 <clCreateBuffer@plt>
mov    %eax,-0x30(%rbp)
mov    -0x2c(%rbp),%edi
lea    0xc5c(%rip),%rsi
mov    %r14,%rdx
mov    $0x165,%ecx
call   1130 <check_error@plt>
mov    0x2aab(%rip),%rax
mov    (%rax),%edx
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
mov    %ebx,%esi
xor    %ecx,%ecx
mov    $0x100,%r8d
mov    -0x60(%rbp),%r9
call   11c0 <clEnqueueWriteBuffer@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
lea    0xc25(%rip),%rsi
mov    %eax,%edi
mov    %r14,%rdx
mov    $0x17f,%ecx
call   1130 <check_error@plt>
lea    -0x34(%rbp),%rcx
mov    %r15d,%edi
xor    %esi,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
mov    %eax,-0x2c(%rbp)
lea    -0x30(%rbp),%rcx
mov    %r15d,%edi
mov    $0x1,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
or     %eax,-0x2c(%rbp)
lea    -0x54(%rbp),%rcx
mov    %r15d,%edi
mov    $0x2,%esi
mov    $0x4,%edx
call   11b0 <clSetKernelArg@plt>
or     -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
lea    0xbd9(%rip),%rsi
mov    %eax,%edi
mov    %r14,%rdx
mov    $0x198,%ecx
call   1130 <check_error@plt>
movaps 0xa23(%rip),%xmm0
movaps %xmm0,-0xa0(%rbp)
movaps %xmm0,-0x90(%rbp)
xor    %eax,%eax
call   1110 <wtime@plt>
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
lea    -0xa0(%rbp),%rbx
lea    -0x90(%rbp),%r14
mov    %r12d,%edi
mov    %r15d,%esi
mov    $0x2,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
mov    %r14,%r9
call   10d0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
mov    %r12d,%edi
call   1060 <clFinish@plt>
mov    %eax,-0x2c(%rbp)
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
mov    %r15d,%esi
mov    $0x2,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
mov    %r14,%r9
call   10d0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
mov    %r12d,%edi
call   1060 <clFinish@plt>
mov    %eax,-0x2c(%rbp)
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
mov    %r15d,%esi
mov    $0x2,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
mov    %r14,%r9
call   10d0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
mov    %r12d,%edi
call   1060 <clFinish@plt>
mov    %eax,-0x2c(%rbp)
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
mov    %r15d,%esi
mov    $0x2,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
mov    %r14,%r9
call   10d0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
mov    %r12d,%edi
call   1060 <clFinish@plt>
mov    %eax,-0x2c(%rbp)
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
mov    %r15d,%r13d
mov    %r15d,%esi
mov    $0x2,%edx
xor    %ecx,%ecx
mov    %rbx,%r8
mov    %r14,%r9
call   10d0 <clEnqueueNDRangeKernel@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
mov    %r12d,%edi
call   1060 <clFinish@plt>
mov    %eax,-0x2c(%rbp)
xor    %eax,%eax
call   1110 <wtime@plt>
mov    -0x2c(%rbp),%edi
lea    0xa74(%rip),%rsi
lea    0x8d6(%rip),%rbx
mov    %rbx,%rdx
mov    $0x1c8,%ecx
call   1130 <check_error@plt>
mov    -0x30(%rbp),%esi
mov    0x2875(%rip),%rax
mov    (%rax),%edx
sub    $0x20,%rsp
xorps  %xmm0,%xmm0
movups %xmm0,0x8(%rsp)
movl   $0x0,(%rsp)
mov    %r12d,%edi
xor    %ecx,%ecx
mov    $0x100,%r8d
mov    -0x70(%rbp),%r15
mov    %r15,%r9
call   1160 <clEnqueueReadBuffer@plt>
add    $0x20,%rsp
mov    %eax,-0x2c(%rbp)
lea    0xa39(%rip),%rsi
mov    %eax,%edi
mov    %rbx,%rdx
mov    $0x1e1,%ecx
call   1130 <check_error@plt>
mov    -0x2c(%rbp),%eax
mov    0x27fa(%rip),%rcx
cmp    (%rcx),%eax
je     17d6 <main+0x536>
lea    0xa3a(%rip),%rdi
call   1080 <puts@plt>
mov    $0xa,%edi
call   1050 <putchar@plt>
xor    %ebx,%ebx
lea    0xa14(%rip),%r14
nopl   0x0(%rax)
movss  (%r15,%rbx,4),%xmm0
cvtss2sd %xmm0,%xmm0
mov    %r14,%rdi
mov    %ebx,%esi
mov    $0x1,%al
call   1100 <printf@plt>
add    $0x1,%rbx
cmp    $0x40,%rbx
jne    17f0 <main+0x550>
mov    -0x34(%rbp),%edi
call   1180 <clReleaseMemObject@plt>
mov    -0x30(%rbp),%edi
call   1180 <clReleaseMemObject@plt>
call   1180 <clReleaseMemObject@plt>
mov    -0x50(%rbp),%edi
call   1170 <clReleaseContext@plt>
mov    %r12d,%edi
call   1140 <clReleaseCommandQueue@plt>
mov    -0x4c(%rbp),%edi
call   10b0 <clReleaseProgram@plt>
mov    %r13d,%edi
call   1090 <clReleaseKernel@plt>
mov    -0x60(%rbp),%rdi
call   1040 <free@plt>
mov    %r15,%rdi
call   1040 <free@plt>
xor    %eax,%eax
mov    -0x68(%rbp),%rsp
jmp    1873 <main+0x5d3>
lea    0x9da(%rip),%rdi
call   1080 <puts@plt>
mov    0x2757(%rip),%rax
mov    (%rax),%eax
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [18 x i8] c"Finding platforms\00"
@.str.1 = [169 x i8] c"/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/LearnOpenCLFromScratch/dgemm/bench/bench.c\00"
@.str.2 = [19 x i8] c"Found 0 platforms\0A\00"
@EXIT_FAILURE = global i32 0
@.str.3 = [24 x i8] c"Getting platforms's IDs\00"
@CL_DEVICE_TYPE_DEFAULT = global i32 0
@CL_SUCCESS = global i32 0
@.str.4 = [18 x i8] c"No devices found\0A\00"
@.str.5 = [17 x i8] c"Creating context\00"
@.str.6 = [23 x i8] c"Creating command queue\00"
@.str.7 = [15 x i8] c"ds_read_b32.cl\00"
@.str.8 = [29 x i8] c"Creating program from source\00"
@.str.9 = [14 x i8] c"Build program\00"
@.str.10 = [11 x i8] c"microbench\00"
@.str.11 = [16 x i8] c"Creating kernel\00"
@CL_MEM_READ_WRITE = global i32 0
@.str.12 = [21 x i8] c"Creating buffer d_in\00"
@.str.13 = [22 x i8] c"Creating buffer d_out\00"
@CL_TRUE = global i32 0
@.str.14 = [21 x i8] c"Copying h_in to d_in\00"
@.str.15 = [25 x i8] c"Setting kernel arguments\00"
@__const.main.global = [2 x i64] [i64 8, i64 8]
@__const.main.local = [2 x i64] [i64 8, i64 8]
@.str.16 = [29 x i8] c"Waiting for kernel to finish\00"
@.str.17 = [23 x i8] c"Copying d_out to h_out\00"
@.str.18 = [36 x i8] c"Error: Failed to read output array\0A\00"
@.str.19 = [2 x i8] c"\0A\00"
@.str.20 = [14 x i8] c"out[%d] = %f\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca float*
%9 = alloca float*
%10 = alloca i32
%11 = alloca i32*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i64
%20 = alloca i8*
%21 = alloca i64
%22 = alloca i32
%23 = alloca i8*
%24 = alloca [2 x i64]
%25 = alloca [2 x i64]
%26 = alloca double
%27 = alloca i32
%28 = alloca float
%29 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%30 = call float* @malloc(i32 256)
store float* %30, float** %8
%31 = call float* @malloc(i32 256)
store float* %31, float** %9
store i32 0, i32* %10
%32 = call i32 @clGetPlatformIDs(i64 0, i32* null, i64* %19)
store i32 %32, i32* %6
%33 = load i32, i32* %6
%34 = call i32 @check_error(i32 %33, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 205)
%35 = load i64, i64* %19
%36 = icmp eq i64 %35, 0
br i1 %36, label %37, label %40
37: ; preds = %2
%38 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.2, i64 0, i64 0))
%39 = load i32, i32* @EXIT_FAILURE
store i32 %39, i32* %3
br label %197
40: ; preds = %2
%41 = load i64, i64* %19
%42 = call i8* @llvm.stacksave()
store i8* %42, i8** %20
%43 = alloca i32, i64 %41
store i64 %41, i64* %21
%44 = load i64, i64* %19
%45 = call i32 @clGetPlatformIDs(i64 %44, i32* %43, i64* null)
store i32 %45, i32* %6
%46 = load i32, i32* %6
%47 = call i32 @check_error(i32 %46, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 218)
store i32 0, i32* %22
br label %48
48: ; preds = %65, %40
%49 = load i32, i32* %22
%50 = sext i32 %49 to i64
%51 = load i64, i64* %19
%52 = icmp slt i64 %50, %51
br i1 %52, label %53, label %68
53: ; preds = %48
%54 = load i32, i32* %22
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %43, i64 %55
%57 = load i32, i32* %56
%58 = load i32, i32* @CL_DEVICE_TYPE_DEFAULT
%59 = call i32 @clGetDeviceIDs(i32 %57, i32 %58, i32 1, i32** %11, i32* null)
store i32 %59, i32* %6
%60 = load i32, i32* %6
%61 = load i32, i32* @CL_SUCCESS
%62 = icmp eq i32 %60, %61
br i1 %62, label %63, label %64
63: ; preds = %53
br label %68
64: ; preds = %53
br label %65
65: ; preds = %64
%66 = load i32, i32* %22
%67 = add nsw i32 %66, 1
store i32 %67, i32* %22
br label %48
68: ; preds = %63, %48
%69 = load i32*, i32** %11
%70 = icmp eq i32* %69, null
br i1 %70, label %71, label %73
71: ; preds = %68
%72 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.4, i64 0, i64 0))
br label %73
73: ; preds = %71, %68
%74 = call i32 @clCreateContext(i32 0, i32 1, i32** %11, i32* null, i32* null, i32* %6)
store i32 %74, i32* %12
%75 = load i32, i32* %6
%76 = call i32 @check_error(i32 %75, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.5, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 260)
%77 = load i32, i32* %12
%78 = load i32*, i32** %11
%79 = call i32 @clCreateCommandQueue(i32 %77, i32* %78, i32 0, i32* %6)
store i32 %79, i32* %13
%80 = load i32, i32* %6
%81 = call i32 @check_error(i32 %80, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.6, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 275)
%82 = call i8* @getKernelSource(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.7, i64 0, i64 0))
store i8* %82, i8** %23
%83 = load i32, i32* %12
%84 = call i32 @clCreateProgramWithSource(i32 %83, i32 1, i8** %23, i32* null, i32* %6)
store i32 %84, i32* %14
%85 = load i32, i32* %6
%86 = call i32 @check_error(i32 %85, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.8, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 296)
%87 = load i32, i32* %14
%88 = call i32 @clBuildProgram(i32 %87, i32 0, i32* null, i32* null, i32* null, i32* null)
store i32 %88, i32* %6
%89 = load i32, i32* %6
%90 = call i32 @check_error(i32 %89, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.9, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 315)
%91 = load i32, i32* %14
%92 = call i32 @clCreateKernel(i32 %91, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.10, i64 0, i64 0), i32* %6)
store i32 %92, i32* %15
%93 = load i32, i32* %6
%94 = call i32 @check_error(i32 %93, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 329)
%95 = load i32, i32* %12
%96 = load i32, i32* @CL_MEM_READ_WRITE
%97 = call i32 @clCreateBuffer(i32 %95, i32 %96, i32 256, i32* null, i32* %6)
store i32 %97, i32* %16
%98 = load i32, i32* %6
%99 = call i32 @check_error(i32 %98, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.12, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 350)
%100 = load i32, i32* %12
%101 = load i32, i32* @CL_MEM_READ_WRITE
%102 = call i32 @clCreateBuffer(i32 %100, i32 %101, i32 256, i32* null, i32* %6)
store i32 %102, i32* %17
%103 = load i32, i32* %6
%104 = call i32 @check_error(i32 %103, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.13, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 357)
%105 = load i32, i32* %13
%106 = load i32, i32* %16
%107 = load i32, i32* @CL_TRUE
%108 = load float*, float** %8
%109 = call i32 @clEnqueueWriteBuffer(i32 %105, i32 %106, i32 %107, i32 0, i32 256, float* %108, i32 0, i32* null, i32* null)
store i32 %109, i32* %6
%110 = load i32, i32* %6
%111 = call i32 @check_error(i32 %110, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.14, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 383)
%112 = load i32, i32* %15
%113 = call i32 @clSetKernelArg(i32 %112, i32 0, i32 4, i32* %16)
store i32 %113, i32* %6
%114 = load i32, i32* %15
%115 = call i32 @clSetKernelArg(i32 %114, i32 1, i32 4, i32* %17)
%116 = load i32, i32* %6
%117 = or i32 %116, %115
store i32 %117, i32* %6
%118 = load i32, i32* %15
%119 = call i32 @clSetKernelArg(i32 %118, i32 2, i32 4, i32* %10)
%120 = load i32, i32* %6
%121 = or i32 %120, %119
store i32 %121, i32* %6
%122 = load i32, i32* %6
%123 = call i32 @check_error(i32 %122, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 408)
%124 = bitcast [2 x i64]* %24 to i8*
%125 = bitcast [2 x i64]* %25 to i8*
%126 = call double (...) @wtime()
store double %126, double* %26
store i32 0, i32* %27
br label %127
127: ; preds = %138, %73
%128 = load i32, i32* %27
%129 = icmp slt i32 %128, 5
br i1 %129, label %130, label %141
130: ; preds = %127
%131 = load i32, i32* %13
%132 = load i32, i32* %15
%133 = getelementptr inbounds [2 x i64], [2 x i64]* %24, i64 0, i64 0
%134 = getelementptr inbounds [2 x i64], [2 x i64]* %25, i64 0, i64 0
%135 = call i32 @clEnqueueNDRangeKernel(i32 %131, i32 %132, i32 2, i32* null, i64* %133, i64* %134, i32 0, i32* null, i32* null)
store i32 %135, i32* %6
%136 = load i32, i32* %13
%137 = call i32 @clFinish(i32 %136)
store i32 %137, i32* %6
br label %138
138: ; preds = %130
%139 = load i32, i32* %27
%140 = add nsw i32 %139, 1
store i32 %140, i32* %27
br label %127
141: ; preds = %127
%142 = call double (...) @wtime()
%143 = load double, double* %26
%144 = fsub double %142, %143
%145 = fdiv double %144, 5.000000e+00
store double %145, double* %26
%146 = load i32, i32* %6
%147 = call i32 @check_error(i32 %146, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.16, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 456)
%148 = load i32, i32* %13
%149 = load i32, i32* %17
%150 = load i32, i32* @CL_TRUE
%151 = load float*, float** %9
%152 = call i32 @clEnqueueReadBuffer(i32 %148, i32 %149, i32 %150, i32 0, i32 256, float* %151, i32 0, i32* null, i32* null)
store i32 %152, i32* %6
%153 = load i32, i32* %6
%154 = call i32 @check_error(i32 %153, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.17, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 481)
%155 = load i32, i32* %6
%156 = load i32, i32* @CL_SUCCESS
%157 = icmp ne i32 %155, %156
br i1 %157, label %158, label %160
158: ; preds = %141
%159 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.18, i64 0, i64 0))
br label %160
160: ; preds = %158, %141
%161 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.19, i64 0, i64 0))
store i32 0, i32* %7
store float 0.000000e+00, float* %28
store i32 0, i32* %29
br label %162
162: ; preds = %174, %160
%163 = load i32, i32* %29
%164 = icmp slt i32 %163, 64
br i1 %164, label %165, label %177
165: ; preds = %162
%166 = load i32, i32* %29
%167 = load float*, float** %9
%168 = load i32, i32* %29
%169 = sext i32 %168 to i64
%170 = getelementptr inbounds float, float* %167, i64 %169
%171 = load float, float* %170
%172 = fpext float %171 to double
%173 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.20, i64 0, i64 0), i32 %166, double %172)
br label %174
174: ; preds = %165
%175 = load i32, i32* %29
%176 = add nsw i32 %175, 1
store i32 %176, i32* %29
br label %162
177: ; preds = %162
%178 = load i32, i32* %16
%179 = call i32 @clReleaseMemObject(i32 %178)
%180 = load i32, i32* %17
%181 = call i32 @clReleaseMemObject(i32 %180)
%182 = load i32, i32* %18
%183 = call i32 @clReleaseMemObject(i32 %182)
%184 = load i32, i32* %12
%185 = call i32 @clReleaseContext(i32 %184)
%186 = load i32, i32* %13
%187 = call i32 @clReleaseCommandQueue(i32 %186)
%188 = load i32, i32* %14
%189 = call i32 @clReleaseProgram(i32 %188)
%190 = load i32, i32* %15
%191 = call i32 @clReleaseKernel(i32 %190)
%192 = load float*, float** %8
%193 = call i32 @free(float* %192)
%194 = load float*, float** %9
%195 = call i32 @free(float* %194)
store i32 0, i32* %3
%196 = load i8*, i8** %20
br label %197
197: ; preds = %177, %37
%198 = load i32, i32* %3
ret i32 %198
}

LLVM IR (-O2):
@.str = [18 x i8] c"Finding platforms\00"
@.str.1 = [169 x i8] c"/scratch/repos/new/home/jordi_armengol_estape/c-scraper/outputs/2022-01-22/02-19-57/repos/haohaibo/tutorial/refs/heads/master/LearnOpenCLFromScratch/dgemm/bench/bench.c\00"
@EXIT_FAILURE = global i32 0
@.str.3 = [24 x i8] c"Getting platforms's IDs\00"
@CL_DEVICE_TYPE_DEFAULT = global i32 0
@CL_SUCCESS = global i32 0
@.str.5 = [17 x i8] c"Creating context\00"
@.str.6 = [23 x i8] c"Creating command queue\00"
@.str.7 = [15 x i8] c"ds_read_b32.cl\00"
@.str.8 = [29 x i8] c"Creating program from source\00"
@.str.9 = [14 x i8] c"Build program\00"
@.str.10 = [11 x i8] c"microbench\00"
@.str.11 = [16 x i8] c"Creating kernel\00"
@CL_MEM_READ_WRITE = global i32 0
@.str.12 = [21 x i8] c"Creating buffer d_in\00"
@.str.13 = [22 x i8] c"Creating buffer d_out\00"
@CL_TRUE = global i32 0
@.str.14 = [21 x i8] c"Copying h_in to d_in\00"
@.str.15 = [25 x i8] c"Setting kernel arguments\00"
@__const.main.local = [2 x i64] [i64 8, i64 8]
@.str.16 = [29 x i8] c"Waiting for kernel to finish\00"
@.str.17 = [23 x i8] c"Copying d_out to h_out\00"
@.str.20 = [14 x i8] c"out[%d] = %f\0A\00"
@str = [35 x i8] c"Error: Failed to read output array\00"
@str.21 = [17 x i8] c"No devices found\00"
@str.22 = [18 x i8] c"Found 0 platforms\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i64
%9 = alloca i8*
%10 = alloca [2 x i64]
%11 = alloca [2 x i64]
%12 = bitcast i32* %3 to i8*
%13 = tail call float* @malloc(i32 256)
%14 = tail call float* @malloc(i32 256)
%15 = bitcast i32* %4 to i8*
store i32 0, i32* %4
%16 = bitcast i32** %5 to i8*
%17 = bitcast i32* %6 to i8*
%18 = bitcast i32* %7 to i8*
%19 = bitcast i64* %8 to i8*
%20 = call i32 @clGetPlatformIDs(i64 0, i32* null, i64* %8)
store i32 %20, i32* %3
%21 = call i32 @check_error(i32 %20, i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 205)
%22 = load i64, i64* %8
%23 = icmp eq i64 %22, 0
br i1 %23, label %24, label %27
24: ; preds = %2
%25 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @str.22, i64 0, i64 0))
%26 = load i32, i32* @EXIT_FAILURE
br label %139
27: ; preds = %2
%28 = call i8* @llvm.stacksave()
%29 = alloca i32, i64 %22
%30 = load i64, i64* %8
%31 = call i32 @clGetPlatformIDs(i64 %30, i32* %29, i64* null)
store i32 %31, i32* %3
%32 = call i32 @check_error(i32 %31, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 218)
%33 = load i64, i64* %8
%34 = icmp sgt i64 %33, 0
br i1 %34, label %35, label %50
35: ; preds = %27, %35
%36 = phi i64 [ %43, %35 ], [ 0, %27 ]
%37 = getelementptr inbounds i32, i32* %29, i64 %36
%38 = load i32, i32* %37
%39 = load i32, i32* @CL_DEVICE_TYPE_DEFAULT
%40 = call i32 @clGetDeviceIDs(i32 %38, i32 %39, i32 1, i32** %5, i32* null)
store i32 %40, i32* %3
%41 = load i32, i32* @CL_SUCCESS
%42 = icmp ne i32 %40, %41
%43 = add nuw nsw i64 %36, 1
%44 = load i64, i64* %8
%45 = icmp sgt i64 %44, %43
%46 = select i1 %42, i1 %45, i1 false
br i1 %46, label %35, label %47
47: ; preds = %35
%48 = load i32*, i32** %5
%49 = icmp eq i32* %48, null
br i1 %49, label %50, label %52
50: ; preds = %27, %47
%51 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @str.21, i64 0, i64 0))
br label %52
52: ; preds = %50, %47
%53 = call i32 @clCreateContext(i32 0, i32 1, i32** %5, i32* null, i32* null, i32* %3)
%54 = load i32, i32* %3
%55 = call i32 @check_error(i32 %54, i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.5, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 260)
%56 = load i32*, i32** %5
%57 = call i32 @clCreateCommandQueue(i32 %53, i32* %56, i32 0, i32* %3)
%58 = load i32, i32* %3
%59 = call i32 @check_error(i32 %58, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.6, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 275)
%60 = bitcast i8** %9 to i8*
%61 = call i8* @getKernelSource(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.7, i64 0, i64 0))
store i8* %61, i8** %9
%62 = call i32 @clCreateProgramWithSource(i32 %53, i32 1, i8** %9, i32* null, i32* %3)
%63 = load i32, i32* %3
%64 = call i32 @check_error(i32 %63, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.8, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 296)
%65 = call i32 @clBuildProgram(i32 %62, i32 0, i32* null, i32* null, i32* null, i32* null)
store i32 %65, i32* %3
%66 = call i32 @check_error(i32 %65, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.9, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 315)
%67 = call i32 @clCreateKernel(i32 %62, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.10, i64 0, i64 0), i32* %3)
%68 = load i32, i32* %3
%69 = call i32 @check_error(i32 %68, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 329)
%70 = load i32, i32* @CL_MEM_READ_WRITE
%71 = call i32 @clCreateBuffer(i32 %53, i32 %70, i32 256, i32* null, i32* %3)
store i32 %71, i32* %6
%72 = load i32, i32* %3
%73 = call i32 @check_error(i32 %72, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.12, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 350)
%74 = load i32, i32* @CL_MEM_READ_WRITE
%75 = call i32 @clCreateBuffer(i32 %53, i32 %74, i32 256, i32* null, i32* %3)
store i32 %75, i32* %7
%76 = load i32, i32* %3
%77 = call i32 @check_error(i32 %76, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.13, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 357)
%78 = load i32, i32* @CL_TRUE
%79 = call i32 @clEnqueueWriteBuffer(i32 %57, i32 %71, i32 %78, i32 0, i32 256, float* %13, i32 0, i32* null, i32* null)
store i32 %79, i32* %3
%80 = call i32 @check_error(i32 %79, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.14, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 383)
%81 = call i32 @clSetKernelArg(i32 %67, i32 0, i32 4, i32* %6)
store i32 %81, i32* %3
%82 = call i32 @clSetKernelArg(i32 %67, i32 1, i32 4, i32* %7)
%83 = load i32, i32* %3
%84 = or i32 %83, %82
store i32 %84, i32* %3
%85 = call i32 @clSetKernelArg(i32 %67, i32 2, i32 4, i32* %4)
%86 = load i32, i32* %3
%87 = or i32 %86, %85
store i32 %87, i32* %3
%88 = call i32 @check_error(i32 %87, i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 408)
%89 = bitcast [2 x i64]* %10 to i8*
%90 = bitcast [2 x i64]* %11 to i8*
%91 = call double (...) @wtime()
%92 = getelementptr inbounds [2 x i64], [2 x i64]* %10, i64 0, i64 0
%93 = getelementptr inbounds [2 x i64], [2 x i64]* %11, i64 0, i64 0
%94 = call i32 @clEnqueueNDRangeKernel(i32 %57, i32 %67, i32 2, i32* null, i64* %92, i64* %93, i32 0, i32* null, i32* null)
store i32 %94, i32* %3
%95 = call i32 @clFinish(i32 %57)
store i32 %95, i32* %3
%96 = call i32 @clEnqueueNDRangeKernel(i32 %57, i32 %67, i32 2, i32* null, i64* %92, i64* %93, i32 0, i32* null, i32* null)
store i32 %96, i32* %3
%97 = call i32 @clFinish(i32 %57)
store i32 %97, i32* %3
%98 = call i32 @clEnqueueNDRangeKernel(i32 %57, i32 %67, i32 2, i32* null, i64* %92, i64* %93, i32 0, i32* null, i32* null)
store i32 %98, i32* %3
%99 = call i32 @clFinish(i32 %57)
store i32 %99, i32* %3
%100 = call i32 @clEnqueueNDRangeKernel(i32 %57, i32 %67, i32 2, i32* null, i64* %92, i64* %93, i32 0, i32* null, i32* null)
store i32 %100, i32* %3
%101 = call i32 @clFinish(i32 %57)
store i32 %101, i32* %3
%102 = call i32 @clEnqueueNDRangeKernel(i32 %57, i32 %67, i32 2, i32* null, i64* %92, i64* %93, i32 0, i32* null, i32* null)
store i32 %102, i32* %3
%103 = call i32 @clFinish(i32 %57)
store i32 %103, i32* %3
%104 = call double (...) @wtime()
%105 = load i32, i32* %3
%106 = call i32 @check_error(i32 %105, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.16, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 456)
%107 = load i32, i32* %7
%108 = load i32, i32* @CL_TRUE
%109 = call i32 @clEnqueueReadBuffer(i32 %57, i32 %107, i32 %108, i32 0, i32 256, float* %14, i32 0, i32* null, i32* null)
store i32 %109, i32* %3
%110 = call i32 @check_error(i32 %109, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.17, i64 0, i64 0), i8* getelementptr inbounds ([169 x i8], [169 x i8]* @.str.1, i64 0, i64 0), i32 481)
%111 = load i32, i32* %3
%112 = load i32, i32* @CL_SUCCESS
%113 = icmp eq i32 %111, %112
br i1 %113, label %116, label %114
114: ; preds = %52
%115 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([35 x i8], [35 x i8]* @str, i64 0, i64 0))
br label %116
116: ; preds = %114, %52
%117 = call i32 @putchar(i32 10)
br label %130
118: ; preds = %130
%119 = load i32, i32* %6
%120 = call i32 @clReleaseMemObject(i32 %119)
%121 = load i32, i32* %7
%122 = call i32 @clReleaseMemObject(i32 %121)
%123 = call i32 @clReleaseMemObject(i32 undef)
%124 = call i32 @clReleaseContext(i32 %53)
%125 = call i32 @clReleaseCommandQueue(i32 %57)
%126 = call i32 @clReleaseProgram(i32 %62)
%127 = call i32 @clReleaseKernel(i32 %67)
%128 = call i32 @free(float* %13)
%129 = call i32 @free(float* %14)
br label %139
130: ; preds = %116, %130
%131 = phi i64 [ 0, %116 ], [ %137, %130 ]
%132 = getelementptr inbounds float, float* %14, i64 %131
%133 = load float, float* %132
%134 = fpext float %133 to double
%135 = trunc i64 %131 to i32
%136 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @.str.20, i64 0, i64 0), i32 %135, double %134)
%137 = add nuw nsw i64 %131, 1
%138 = icmp eq i64 %137, 64
br i1 %138, label %118, label %130
139: ; preds = %118, %24
%140 = phi i32 [ %26, %24 ], [ 0, %118 ]
ret i32 %140
}