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

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ __tgt_register_requires(int);
int /*<<< orphan*/ init(int *, int *, int *);
int omp_get_default_device();
int const omp_get_initial_device();
scalar_t__ omp_target_alloc(int, int const);
int omp_target_associate_ptr(int *, int *, int, int /*<<< orphan*/, int const);
int omp_target_disassociate_ptr(int *, int const);
int /*<<< orphan*/ omp_target_free(int *, int const);
scalar_t__ omp_target_is_present(int *, int const);
int /*<<< orphan*/ omp_target_memcpy(int *, int *, int, int /*<<< orphan*/,
                                     int /*<<< orphan*/, int const, int const);
int /*<<< orphan*/ printf(char *, ...);
int main(int argc, char *argv[]) {
  const int device = omp_get_default_device();
  __tgt_register_requires(8);
  printf("Initial device: %d\n", omp_get_initial_device());
  int A[1024], B[1024], C[1024];
  init(A, B, C);
  int *pA, *pB, *pC;
  pA = &A[0];
  pB = &B[0];
  pC = &C[0];
  int *d_A = (int *)omp_target_alloc(1024 * sizeof(int), device);
  int *d_B = (int *)omp_target_alloc(1024 * sizeof(int), device);
  int *d_C = (int *)omp_target_alloc(1024 * sizeof(int), device);
  printf("omp_target_alloc %s\n", d_A && d_B && d_C ? "succeeded" : "failed");
  omp_target_memcpy(d_B, pB, 1024 * sizeof(int), 0, 0, device,
                    omp_get_initial_device());
  omp_target_memcpy(d_C, pC, 1024 * sizeof(int), 0, 0, device,
                    omp_get_initial_device());
#pragma omp target is_device_ptr(d_A, d_B, d_C) device(device)
  {
#pragma omp parallel for schedule(static, 1)
    for (int i = 0; i < 1024; i++) {
      d_A[i] = d_B[i] + d_C[i] + 1;
    }
  }
  omp_target_memcpy(pA, d_A, 1024 * sizeof(int), 0, 0, omp_get_initial_device(),
                    device);
  int fail = 0;
  for (int i = 0; i < 1024; ++i) {
    if (A[i] != i + 2)
      fail++;
  }
  if (fail) {
    printf("Test omp_target_memcpy: Failed\n");
  } else {
    printf("Test omp_target_memcpy: Succeeded\n");
  }
  init(A, B, C);
  if (!omp_target_is_present(B, device)) {
    printf("B is not present, associating it...\n");
    int rc = omp_target_associate_ptr(B, d_B, 1024 * sizeof(int), 0, device);
    printf("omp_target_associate_ptr B %s\n", !rc ? "succeeded" : "failed");
  }
  if (!omp_target_is_present(C, device)) {
    printf("C is not present, associating it...\n");
    int rc = omp_target_associate_ptr(C, d_C, 1024 * sizeof(int), 0, device);
    printf("omp_target_associate_ptr C %s\n", !rc ? "succeeded" : "failed");
  }
#pragma omp target data map(from : B, C) device(device)
  {
    printf("Inside target data: A is%s present\n",
           omp_target_is_present(A, device) ? "" : " not");
    printf("Inside target data: B is%s present\n",
           omp_target_is_present(B, device) ? "" : " not");
    printf("Inside target data: C is%s present\n",
           omp_target_is_present(C, device) ? "" : " not");
#pragma omp target map(from : A) device(device)
    {
#pragma omp parallel for schedule(static, 1)
      for (int i = 0; i < 1024; i++)
        A[i] = B[i] + C[i] + 1;
    }
  }
  if (omp_target_is_present(B, device)) {
    printf("B is present, disassociating it...\n");
    int rc = omp_target_disassociate_ptr(B, device);
    printf("omp_target_disassociate_ptr B %s\n", !rc ? "succeeded" : "failed");
  }
  if (omp_target_is_present(C, device)) {
    printf("C is present, disassociating it...\n");
    int rc = omp_target_disassociate_ptr(C, device);
    printf("omp_target_disassociate_ptr C %s\n", !rc ? "succeeded" : "failed");
  }
  fail = 0;
  for (int i = 0; i < 1024; ++i) {
    if (A[i] != i + 2)
      fail++;
  }
  if (fail) {
    printf("Test omp_target_associate_ptr: Failed\n");
  } else {
    printf("Test omp_target_associate_ptr: Succeeded\n");
  }
  omp_target_free(d_A, device);
  omp_target_free(d_B, device);
  omp_target_free(d_C, device);
  printf("Done!\n");
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30c0,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    $0x0,%al
call   1060 <omp_get_default_device@plt>
mov    %eax,-0x14(%rbp)
mov    $0x8,%edi
call   10c0 <__tgt_register_requires@plt>
mov    $0x0,%al
call   10b0 <omp_get_initial_device@plt>
mov    %eax,%esi
lea    0xe13(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x1020(%rbp),%rdi
lea    -0x2020(%rbp),%rsi
lea    -0x3020(%rbp),%rdx
call   10a0 <init@plt>
lea    -0x1020(%rbp),%rax
mov    %rax,-0x3028(%rbp)
lea    -0x2020(%rbp),%rax
mov    %rax,-0x3030(%rbp)
lea    -0x3020(%rbp),%rax
mov    %rax,-0x3038(%rbp)
mov    -0x14(%rbp),%esi
mov    $0x1000,%edi
call   10d0 <omp_target_alloc@plt>
mov    %rax,-0x3040(%rbp)
mov    -0x14(%rbp),%esi
mov    $0x1000,%edi
call   10d0 <omp_target_alloc@plt>
mov    %rax,-0x3048(%rbp)
mov    -0x14(%rbp),%esi
mov    $0x1000,%edi
call   10d0 <omp_target_alloc@plt>
mov    %rax,-0x3050(%rbp)
xor    %eax,%eax
cmpq   $0x0,-0x3040(%rbp)
mov    %al,-0x3075(%rbp)
je     12b1 <main+0x101>
xor    %eax,%eax
cmpq   $0x0,-0x3048(%rbp)
mov    %al,-0x3075(%rbp)
je     12b1 <main+0x101>
cmpq   $0x0,-0x3050(%rbp)
setne  %al
mov    %al,-0x3075(%rbp)
mov    -0x3075(%rbp),%cl
lea    0xd75(%rip),%rsi
lea    0xd64(%rip),%rax
test   $0x1,%cl
cmovne %rax,%rsi
lea    0xd41(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
mov    -0x3048(%rbp),%rax
mov    %rax,-0x30a8(%rbp)
mov    -0x3030(%rbp),%rax
mov    %rax,-0x30a0(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x3094(%rbp)
mov    $0x0,%al
call   10b0 <omp_get_initial_device@plt>
mov    -0x30a8(%rbp),%rdi
mov    -0x30a0(%rbp),%rsi
mov    -0x3094(%rbp),%r9d
mov    $0x1000,%edx
xor    %r8d,%r8d
mov    %r8d,%ecx
mov    %eax,(%rsp)
call   1040 <omp_target_memcpy@plt>
mov    -0x3050(%rbp),%rax
mov    %rax,-0x3090(%rbp)
mov    -0x3038(%rbp),%rax
mov    %rax,-0x3088(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x307c(%rbp)
mov    $0x0,%al
call   10b0 <omp_get_initial_device@plt>
mov    -0x3090(%rbp),%rdi
mov    -0x3088(%rbp),%rsi
mov    -0x307c(%rbp),%r9d
mov    $0x1000,%edx
xor    %r8d,%r8d
mov    %r8d,%ecx
mov    %eax,(%rsp)
call   1040 <omp_target_memcpy@plt>
movl   $0x0,-0x3054(%rbp)
cmpl   $0x400,-0x3054(%rbp)
jge    13e6 <main+0x236>
mov    -0x3048(%rbp),%rax
movslq -0x3054(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x3050(%rbp),%rax
movslq -0x3054(%rbp),%rcx
add    (%rax,%rcx,4),%edx
add    $0x1,%edx
mov    -0x3040(%rbp),%rax
movslq -0x3054(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x3054(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3054(%rbp)
jmp    138c <main+0x1dc>
mov    -0x3028(%rbp),%rax
mov    %rax,-0x30b8(%rbp)
mov    -0x3040(%rbp),%rax
mov    %rax,-0x30b0(%rbp)
mov    $0x0,%al
call   10b0 <omp_get_initial_device@plt>
mov    -0x30b8(%rbp),%rdi
mov    -0x30b0(%rbp),%rsi
mov    %eax,%r9d
mov    -0x14(%rbp),%eax
mov    $0x1000,%edx
xor    %r8d,%r8d
mov    %r8d,%ecx
mov    %eax,(%rsp)
call   1040 <omp_target_memcpy@plt>
movl   $0x0,-0x3058(%rbp)
movl   $0x0,-0x305c(%rbp)
cmpl   $0x400,-0x305c(%rbp)
jge    149b <main+0x2eb>
movslq -0x305c(%rbp),%rax
mov    -0x1020(%rbp,%rax,4),%eax
mov    -0x305c(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
je     1482 <main+0x2d2>
mov    -0x3058(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3058(%rbp)
jmp    1487 <main+0x2d7>
mov    -0x305c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x305c(%rbp)
jmp    1444 <main+0x294>
cmpl   $0x0,-0x3058(%rbp)
je     14bb <main+0x30b>
lea    0xb8b(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
jmp    14c9 <main+0x319>
lea    0xb98(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x1020(%rbp),%rdi
lea    -0x2020(%rbp),%rsi
lea    -0x3020(%rbp),%rdx
call   10a0 <init@plt>
lea    -0x2020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
cmp    $0x0,%rax
jne    155e <main+0x3ae>
lea    0xb7a(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x2020(%rbp),%rdi
mov    -0x3048(%rbp),%rsi
mov    -0x14(%rbp),%r8d
mov    $0x1000,%edx
xor    %ecx,%ecx
call   1090 <omp_target_associate_ptr@plt>
mov    %eax,-0x3060(%rbp)
cmpl   $0x0,-0x3060(%rbp)
setne  %cl
xor    $0xff,%cl
lea    0xaf1(%rip),%rsi
lea    0xae0(%rip),%rax
test   $0x1,%cl
cmovne %rax,%rsi
lea    0xb4b(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x3020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
cmp    $0x0,%rax
jne    15d9 <main+0x429>
lea    0xb43(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x3020(%rbp),%rdi
mov    -0x3050(%rbp),%rsi
mov    -0x14(%rbp),%r8d
mov    $0x1000,%edx
xor    %ecx,%ecx
call   1090 <omp_target_associate_ptr@plt>
mov    %eax,-0x3064(%rbp)
cmpl   $0x0,-0x3064(%rbp)
setne  %cl
xor    $0xff,%cl
lea    0xa76(%rip),%rsi
lea    0xa65(%rip),%rax
test   $0x1,%cl
cmovne %rax,%rsi
lea    0xb14(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x1020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
mov    %rax,%rcx
lea    0xb37(%rip),%rsi
lea    0xc60(%rip),%rax
cmp    $0x0,%rcx
cmovne %rax,%rsi
lea    0xafd(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x2020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
mov    %rax,%rcx
lea    0xb01(%rip),%rsi
lea    0xc2a(%rip),%rax
cmp    $0x0,%rcx
cmovne %rax,%rsi
lea    0xaf0(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x3020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
mov    %rax,%rcx
lea    0xacb(%rip),%rsi
lea    0xbf4(%rip),%rax
cmp    $0x0,%rcx
cmovne %rax,%rsi
lea    0xade(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
movl   $0x0,-0x3068(%rbp)
cmpl   $0x400,-0x3068(%rbp)
jge    16d6 <main+0x526>
movslq -0x3068(%rbp),%rax
mov    -0x2020(%rbp,%rax,4),%ecx
movslq -0x3068(%rbp),%rax
add    -0x3020(%rbp,%rax,4),%ecx
add    $0x1,%ecx
movslq -0x3068(%rbp),%rax
mov    %ecx,-0x1020(%rbp,%rax,4)
mov    -0x3068(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3068(%rbp)
jmp    1685 <main+0x4d5>
lea    -0x2020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
cmp    $0x0,%rax
je     1742 <main+0x592>
lea    0xa80(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x2020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1080 <omp_target_disassociate_ptr@plt>
mov    %eax,-0x306c(%rbp)
cmpl   $0x0,-0x306c(%rbp)
setne  %cl
xor    $0xff,%cl
lea    0x90d(%rip),%rsi
lea    0x8fc(%rip),%rax
test   $0x1,%cl
cmovne %rax,%rsi
lea    0xa5f(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x3020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1070 <omp_target_is_present@plt>
cmp    $0x0,%rax
je     17ae <main+0x5fe>
lea    0xa5a(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    -0x3020(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1080 <omp_target_disassociate_ptr@plt>
mov    %eax,-0x3070(%rbp)
cmpl   $0x0,-0x3070(%rbp)
setne  %cl
xor    $0xff,%cl
lea    0x8a1(%rip),%rsi
lea    0x890(%rip),%rax
test   $0x1,%cl
cmovne %rax,%rsi
lea    0xa39(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
movl   $0x0,-0x3058(%rbp)
movl   $0x0,-0x3074(%rbp)
cmpl   $0x400,-0x3074(%rbp)
jge    1819 <main+0x669>
movslq -0x3074(%rbp),%rax
mov    -0x1020(%rbp,%rax,4),%eax
mov    -0x3074(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
je     1800 <main+0x650>
mov    -0x3058(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3058(%rbp)
jmp    1805 <main+0x655>
mov    -0x3074(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3074(%rbp)
jmp    17c2 <main+0x612>
cmpl   $0x0,-0x3058(%rbp)
je     1839 <main+0x689>
lea    0x9d5(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
jmp    1847 <main+0x697>
lea    0x9e9(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
mov    -0x3040(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1030 <omp_target_free@plt>
mov    -0x3048(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1030 <omp_target_free@plt>
mov    -0x3050(%rbp),%rdi
mov    -0x14(%rbp),%esi
call   1030 <omp_target_free@plt>
lea    0x9d8(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
xor    %eax,%eax
add    $0x30c0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x3018,%rsp
xor    %eax,%eax
call   1070 <omp_get_default_device@plt>
mov    %eax,%r14d
mov    $0x8,%edi
call   10d0 <__tgt_register_requires@plt>
xor    %eax,%eax
call   10c0 <omp_get_initial_device@plt>
lea    0xe0d(%rip),%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x10(%rsp),%rdi
lea    0x2010(%rsp),%r12
lea    0x1010(%rsp),%rbx
mov    %r12,%rsi
mov    %rbx,%rdx
call   10b0 <init@plt>
mov    $0x1000,%edi
mov    %r14d,%esi
call   10e0 <omp_target_alloc@plt>
mov    %rax,%r13
mov    $0x1000,%edi
mov    %r14d,%esi
call   10e0 <omp_target_alloc@plt>
mov    %rax,%r15
mov    $0x1000,%edi
mov    %r14d,%esi
call   10e0 <omp_target_alloc@plt>
mov    %rax,%rbp
test   %rax,%rax
lea    0xddd(%rip),%rax
lea    0xdcc(%rip),%rsi
cmove  %rax,%rsi
test   %r15,%r15
cmove  %rax,%rsi
test   %r13,%r13
cmove  %rax,%rsi
lea    0xd9e(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
xor    %eax,%eax
call   10c0 <omp_get_initial_device@plt>
mov    %eax,(%rsp)
mov    %r15,%rdi
mov    %r12,%rsi
mov    $0x1000,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
mov    %r14d,%r9d
call   1050 <omp_target_memcpy@plt>
xor    %eax,%eax
call   10c0 <omp_get_initial_device@plt>
mov    %eax,(%rsp)
mov    %rbp,%rdi
mov    %rbx,%rsi
mov    $0x1000,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
mov    %r14d,%r9d
call   1050 <omp_target_memcpy@plt>
lea    0x1000(%r13),%rcx
lea    0x1000(%r15),%rax
lea    0x1000(%rbp),%rdx
cmp    %rax,%r13
setb   %sil
cmp    %rcx,%r15
setb   %bl
cmp    %rdx,%r13
setb   %al
cmp    %rcx,%rbp
setb   %cl
test   %bl,%sil
jne    138d <main+0x1cd>
and    %cl,%al
jne    138d <main+0x1cd>
xor    %eax,%eax
pcmpeqd %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
movdqu (%r15,%rax,4),%xmm1
movdqu 0x10(%r15,%rax,4),%xmm2
movdqu 0x0(%rbp,%rax,4),%xmm3
paddd  %xmm1,%xmm3
movdqu 0x10(%rbp,%rax,4),%xmm1
paddd  %xmm2,%xmm1
psubd  %xmm0,%xmm3
psubd  %xmm0,%xmm1
movdqu %xmm3,0x0(%r13,%rax,4)
movdqu %xmm1,0x10(%r13,%rax,4)
movdqu 0x20(%r15,%rax,4),%xmm1
movdqu 0x30(%r15,%rax,4),%xmm2
movdqu 0x20(%rbp,%rax,4),%xmm3
paddd  %xmm1,%xmm3
movdqu 0x30(%rbp,%rax,4),%xmm1
paddd  %xmm2,%xmm1
psubd  %xmm0,%xmm3
psubd  %xmm0,%xmm1
movdqu %xmm3,0x20(%r13,%rax,4)
movdqu %xmm1,0x30(%r13,%rax,4)
add    $0x10,%rax
cmp    $0x400,%rax
jne    1310 <main+0x150>
jmp    13c1 <main+0x201>
xor    %eax,%eax
nop
mov    (%r15,%rax,4),%ecx
mov    0x0(%rbp,%rax,4),%edx
add    %edx,%ecx
add    $0x1,%ecx
mov    %ecx,0x0(%r13,%rax,4)
mov    0x4(%r15,%rax,4),%ecx
mov    0x4(%rbp,%rax,4),%edx
add    %edx,%ecx
add    $0x1,%ecx
mov    %ecx,0x4(%r13,%rax,4)
add    $0x2,%rax
cmp    $0x400,%rax
jne    1390 <main+0x1d0>
xor    %ebx,%ebx
xor    %eax,%eax
call   10c0 <omp_get_initial_device@plt>
mov    %r14d,(%rsp)
lea    0x10(%rsp),%rdi
mov    %r13,%rsi
mov    $0x1000,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
mov    %eax,%r9d
call   1050 <omp_target_memcpy@plt>
mov    $0x5,%eax
nopl   (%rax)
mov    -0x4(%rsp,%rax,4),%ecx
mov    (%rsp,%rax,4),%edx
lea    -0x3(%rax),%rsi
xor    %edi,%edi
cmp    %rcx,%rsi
setne  %dil
add    %ebx,%edi
lea    -0x2(%rax),%rcx
xor    %esi,%esi
cmp    %rdx,%rcx
setne  %sil
add    %edi,%esi
mov    0x4(%rsp,%rax,4),%ecx
lea    -0x1(%rax),%rdx
xor    %edi,%edi
cmp    %rcx,%rdx
setne  %dil
add    %esi,%edi
mov    0x8(%rsp,%rax,4),%ecx
xor    %ebx,%ebx
cmp    %rcx,%rax
setne  %bl
add    %edi,%ebx
add    $0x4,%rax
cmp    $0x405,%rax
jne    13f0 <main+0x230>
test   %ebx,%ebx
lea    0xce2(%rip),%rax
lea    0xde0(%rip),%rdi
cmove  %rax,%rdi
call   1040 <puts@plt>
lea    0x10(%rsp),%rdi
lea    0x2010(%rsp),%r12
lea    0x1010(%rsp),%rdx
mov    %r12,%rsi
call   10b0 <init@plt>
mov    %r12,%rdi
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
jne    14d0 <main+0x310>
lea    0xcc0(%rip),%rdi
call   1040 <puts@plt>
lea    0x2010(%rsp),%rdi
mov    %r15,%rsi
mov    $0x1000,%edx
xor    %ecx,%ecx
mov    %r14d,%r8d
call   10a0 <omp_target_associate_ptr@plt>
test   %eax,%eax
lea    0xb7c(%rip),%rsi
lea    0xb6b(%rip),%rax
cmove  %rax,%rsi
lea    0xb71(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x1010(%rsp),%rdi
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
jne    152d <main+0x36d>
lea    0xc87(%rip),%rdi
call   1040 <puts@plt>
lea    0x1010(%rsp),%rdi
mov    %rbp,%rsi
mov    $0x1000,%edx
xor    %ecx,%ecx
mov    %r14d,%r8d
call   10a0 <omp_target_associate_ptr@plt>
test   %eax,%eax
lea    0xb1f(%rip),%rsi
lea    0xb0e(%rip),%rax
cmove  %rax,%rsi
lea    0xb33(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x10(%rsp),%rdi
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
lea    0xb58(%rip),%rax
lea    0xac8(%rip),%r12
mov    %r12,%rsi
cmove  %rax,%rsi
lea    0xb1f(%rip),%rdi
xor    %ebx,%ebx
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x2010(%rsp),%rdi
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
mov    %r12,%rsi
lea    0xb1d(%rip),%rax
cmove  %rax,%rsi
lea    0xb17(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x1010(%rsp),%rdi
mov    %r14d,0xc(%rsp)
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
lea    0xaec(%rip),%rax
cmove  %rax,%r12
lea    0xb0a(%rip),%rdi
mov    %r12,%rsi
xor    %eax,%eax
call   1060 <printf@plt>
pcmpeqd %xmm0,%xmm0
nopl   0x0(%rax)
movdqa 0x2010(%rsp,%rbx,4),%xmm1
movdqa 0x2020(%rsp,%rbx,4),%xmm2
movdqa 0x2030(%rsp,%rbx,4),%xmm3
movdqa 0x2040(%rsp,%rbx,4),%xmm4
paddd  0x1010(%rsp,%rbx,4),%xmm1
paddd  0x1020(%rsp,%rbx,4),%xmm2
psubd  %xmm0,%xmm1
psubd  %xmm0,%xmm2
movdqa %xmm1,0x10(%rsp,%rbx,4)
movdqa %xmm2,0x20(%rsp,%rbx,4)
paddd  0x1030(%rsp,%rbx,4),%xmm3
paddd  0x1040(%rsp,%rbx,4),%xmm4
psubd  %xmm0,%xmm3
psubd  %xmm0,%xmm4
movdqa %xmm3,0x30(%rsp,%rbx,4)
movdqa %xmm4,0x40(%rsp,%rbx,4)
add    $0x10,%rbx
cmp    $0x400,%rbx
jne    15d0 <main+0x410>
lea    0x2010(%rsp),%rdi
mov    0xc(%rsp),%r14d
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
je     16a5 <main+0x4e5>
lea    0xba1(%rip),%rdi
call   1040 <puts@plt>
lea    0x2010(%rsp),%rdi
mov    %r14d,%esi
call   1090 <omp_target_disassociate_ptr@plt>
test   %eax,%eax
lea    0x9a7(%rip),%rsi
lea    0x996(%rip),%rax
cmove  %rax,%rsi
lea    0xa4b(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
lea    0x1010(%rsp),%rdi
mov    %r14d,%esi
call   1080 <omp_target_is_present@plt>
test   %rax,%rax
je     16f8 <main+0x538>
lea    0xb2b(%rip),%rdi
call   1040 <puts@plt>
lea    0x1010(%rsp),%rdi
mov    %r14d,%esi
call   1090 <omp_target_disassociate_ptr@plt>
test   %eax,%eax
lea    0x954(%rip),%rsi
lea    0x943(%rip),%rax
cmove  %rax,%rsi
lea    0xa1a(%rip),%rdi
xor    %eax,%eax
call   1060 <printf@plt>
xor    %ecx,%ecx
mov    $0x5,%eax
nop
mov    -0x4(%rsp,%rax,4),%edx
mov    (%rsp,%rax,4),%esi
lea    -0x3(%rax),%rdi
xor    %ebx,%ebx
cmp    %rdx,%rdi
setne  %bl
add    %ecx,%ebx
lea    -0x2(%rax),%rcx
xor    %edx,%edx
cmp    %rsi,%rcx
setne  %dl
add    %ebx,%edx
mov    0x4(%rsp,%rax,4),%ecx
lea    -0x1(%rax),%rsi
xor    %edi,%edi
cmp    %rcx,%rsi
setne  %dil
add    %edx,%edi
mov    0x8(%rsp,%rax,4),%edx
xor    %ecx,%ecx
cmp    %rdx,%rax
setne  %cl
add    %edi,%ecx
add    $0x4,%rax
cmp    $0x405,%rax
jne    1700 <main+0x540>
test   %ecx,%ecx
lea    0xa3e(%rip),%rax
lea    0xa66(%rip),%rdi
cmove  %rax,%rdi
call   1040 <puts@plt>
mov    %r13,%rdi
mov    %r14d,%esi
call   1030 <omp_target_free@plt>
mov    %r15,%rdi
mov    %r14d,%esi
call   1030 <omp_target_free@plt>
mov    %rbp,%rdi
mov    %r14d,%esi
call   1030 <omp_target_free@plt>
lea    0xa2f(%rip),%rdi
call   1040 <puts@plt>
xor    %eax,%eax
add    $0x3018,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [20 x i8] c"Initial device: %d\0A\00"
@.str.1 = [21 x i8] c"omp_target_alloc %s\0A\00"
@.str.2 = [10 x i8] c"succeeded\00"
@.str.3 = [7 x i8] c"failed\00"
@.str.4 = [32 x i8] c"Test omp_target_memcpy: Failed\0A\00"
@.str.5 = [35 x i8] c"Test omp_target_memcpy: Succeeded\0A\00"
@.str.6 = [37 x i8] c"B is not present, associating it...\0A\00"
@.str.7 = [31 x i8] c"omp_target_associate_ptr B %s\0A\00"
@.str.8 = [37 x i8] c"C is not present, associating it...\0A\00"
@.str.9 = [31 x i8] c"omp_target_associate_ptr C %s\0A\00"
@.str.10 = [36 x i8] c"Inside target data: A is%s present\0A\00"
@.str.11 = [1 x i8] zeroinitializer
@.str.12 = [5 x i8] c" not\00"
@.str.13 = [36 x i8] c"Inside target data: B is%s present\0A\00"
@.str.14 = [36 x i8] c"Inside target data: C is%s present\0A\00"
@.str.15 = [36 x i8] c"B is present, disassociating it...\0A\00"
@.str.16 = [34 x i8] c"omp_target_disassociate_ptr B %s\0A\00"
@.str.17 = [36 x i8] c"C is present, disassociating it...\0A\00"
@.str.18 = [34 x i8] c"omp_target_disassociate_ptr C %s\0A\00"
@.str.19 = [39 x i8] c"Test omp_target_associate_ptr: Failed\0A\00"
@.str.20 = [42 x i8] c"Test omp_target_associate_ptr: Succeeded\0A\00"
@.str.21 = [7 x i8] c"Done!\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca [1024 x i32]
%8 = alloca [1024 x i32]
%9 = alloca [1024 x i32]
%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 i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%25 = call i32 (...) @omp_get_default_device()
store i32 %25, i32* %6
%26 = call i32 @__tgt_register_requires(i32 8)
%27 = call i32 (...) @omp_get_initial_device()
%28 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %27)
%29 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 0
%30 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%31 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%32 = call i32 @init(i32* %29, i32* %30, i32* %31)
%33 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 0
store i32* %33, i32** %10
%34 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
store i32* %34, i32** %11
%35 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
store i32* %35, i32** %12
%36 = load i32, i32* %6
%37 = call i64 @omp_target_alloc(i32 4096, i32 %36)
%38 = inttoptr i64 %37 to i32*
store i32* %38, i32** %13
%39 = load i32, i32* %6
%40 = call i64 @omp_target_alloc(i32 4096, i32 %39)
%41 = inttoptr i64 %40 to i32*
store i32* %41, i32** %14
%42 = load i32, i32* %6
%43 = call i64 @omp_target_alloc(i32 4096, i32 %42)
%44 = inttoptr i64 %43 to i32*
store i32* %44, i32** %15
%45 = load i32*, i32** %13
%46 = icmp ne i32* %45, null
br i1 %46, label %47, label %53
47: ; preds = %2
%48 = load i32*, i32** %14
%49 = icmp ne i32* %48, null
br i1 %49, label %50, label %53
50: ; preds = %47
%51 = load i32*, i32** %15
%52 = icmp ne i32* %51, null
br label %53
53: ; preds = %50, %47, %2
%54 = phi i1 [ false, %47 ], [ false, %2 ], [ %52, %50 ]
%55 = zext i1 %54 to i64
%56 = select i1 %54, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%57 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i8* %56)
%58 = load i32*, i32** %14
%59 = load i32*, i32** %11
%60 = load i32, i32* %6
%61 = call i32 (...) @omp_get_initial_device()
%62 = call i32 @omp_target_memcpy(i32* %58, i32* %59, i32 4096, i32 0, i32 0, i32 %60, i32 %61)
%63 = load i32*, i32** %15
%64 = load i32*, i32** %12
%65 = load i32, i32* %6
%66 = call i32 (...) @omp_get_initial_device()
%67 = call i32 @omp_target_memcpy(i32* %63, i32* %64, i32 4096, i32 0, i32 0, i32 %65, i32 %66)
store i32 0, i32* %16
br label %68
68: ; preds = %88, %53
%69 = load i32, i32* %16
%70 = icmp slt i32 %69, 1024
br i1 %70, label %71, label %91
71: ; preds = %68
%72 = load i32*, i32** %14
%73 = load i32, i32* %16
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds i32, i32* %72, i64 %74
%76 = load i32, i32* %75
%77 = load i32*, i32** %15
%78 = load i32, i32* %16
%79 = sext i32 %78 to i64
%80 = getelementptr inbounds i32, i32* %77, i64 %79
%81 = load i32, i32* %80
%82 = add nsw i32 %76, %81
%83 = add nsw i32 %82, 1
%84 = load i32*, i32** %13
%85 = load i32, i32* %16
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds i32, i32* %84, i64 %86
store i32 %83, i32* %87
br label %88
88: ; preds = %71
%89 = load i32, i32* %16
%90 = add nsw i32 %89, 1
store i32 %90, i32* %16
br label %68
91: ; preds = %68
%92 = load i32*, i32** %10
%93 = load i32*, i32** %13
%94 = call i32 (...) @omp_get_initial_device()
%95 = load i32, i32* %6
%96 = call i32 @omp_target_memcpy(i32* %92, i32* %93, i32 4096, i32 0, i32 0, i32 %94, i32 %95)
store i32 0, i32* %17
store i32 0, i32* %18
br label %97
97: ; preds = %112, %91
%98 = load i32, i32* %18
%99 = icmp slt i32 %98, 1024
br i1 %99, label %100, label %115
100: ; preds = %97
%101 = load i32, i32* %18
%102 = sext i32 %101 to i64
%103 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 %102
%104 = load i32, i32* %103
%105 = load i32, i32* %18
%106 = add nsw i32 %105, 2
%107 = icmp ne i32 %104, %106
br i1 %107, label %108, label %111
108: ; preds = %100
%109 = load i32, i32* %17
%110 = add nsw i32 %109, 1
store i32 %110, i32* %17
br label %111
111: ; preds = %108, %100
br label %112
112: ; preds = %111
%113 = load i32, i32* %18
%114 = add nsw i32 %113, 1
store i32 %114, i32* %18
br label %97
115: ; preds = %97
%116 = load i32, i32* %17
%117 = icmp ne i32 %116, 0
br i1 %117, label %118, label %120
118: ; preds = %115
%119 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str.4, i64 0, i64 0))
br label %122
120: ; preds = %115
%121 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @.str.5, i64 0, i64 0))
br label %122
122: ; preds = %120, %118
%123 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 0
%124 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%125 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%126 = call i32 @init(i32* %123, i32* %124, i32* %125)
%127 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%128 = load i32, i32* %6
%129 = call i64 @omp_target_is_present(i32* %127, i32 %128)
%130 = icmp ne i64 %129, 0
br i1 %130, label %143, label %131
131: ; preds = %122
%132 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str.6, i64 0, i64 0))
%133 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%134 = load i32*, i32** %14
%135 = load i32, i32* %6
%136 = call i32 @omp_target_associate_ptr(i32* %133, i32* %134, i32 4096, i32 0, i32 %135)
store i32 %136, i32* %19
%137 = load i32, i32* %19
%138 = icmp ne i32 %137, 0
%139 = xor i1 %138, true
%140 = zext i1 %139 to i64
%141 = select i1 %139, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%142 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.7, i64 0, i64 0), i8* %141)
br label %143
143: ; preds = %131, %122
%144 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%145 = load i32, i32* %6
%146 = call i64 @omp_target_is_present(i32* %144, i32 %145)
%147 = icmp ne i64 %146, 0
br i1 %147, label %160, label %148
148: ; preds = %143
%149 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str.8, i64 0, i64 0))
%150 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%151 = load i32*, i32** %15
%152 = load i32, i32* %6
%153 = call i32 @omp_target_associate_ptr(i32* %150, i32* %151, i32 4096, i32 0, i32 %152)
store i32 %153, i32* %20
%154 = load i32, i32* %20
%155 = icmp ne i32 %154, 0
%156 = xor i1 %155, true
%157 = zext i1 %156 to i64
%158 = select i1 %156, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%159 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.9, i64 0, i64 0), i8* %158)
br label %160
160: ; preds = %148, %143
%161 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 0
%162 = load i32, i32* %6
%163 = call i64 @omp_target_is_present(i32* %161, i32 %162)
%164 = icmp ne i64 %163, 0
%165 = zext i1 %164 to i64
%166 = select i1 %164, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0)
%167 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.10, i64 0, i64 0), i8* %166)
%168 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%169 = load i32, i32* %6
%170 = call i64 @omp_target_is_present(i32* %168, i32 %169)
%171 = icmp ne i64 %170, 0
%172 = zext i1 %171 to i64
%173 = select i1 %171, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0)
%174 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.13, i64 0, i64 0), i8* %173)
%175 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%176 = load i32, i32* %6
%177 = call i64 @omp_target_is_present(i32* %175, i32 %176)
%178 = icmp ne i64 %177, 0
%179 = zext i1 %178 to i64
%180 = select i1 %178, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0)
%181 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.14, i64 0, i64 0), i8* %180)
store i32 0, i32* %21
br label %182
182: ; preds = %199, %160
%183 = load i32, i32* %21
%184 = icmp slt i32 %183, 1024
br i1 %184, label %185, label %202
185: ; preds = %182
%186 = load i32, i32* %21
%187 = sext i32 %186 to i64
%188 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 %187
%189 = load i32, i32* %188
%190 = load i32, i32* %21
%191 = sext i32 %190 to i64
%192 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 %191
%193 = load i32, i32* %192
%194 = add nsw i32 %189, %193
%195 = add nsw i32 %194, 1
%196 = load i32, i32* %21
%197 = sext i32 %196 to i64
%198 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 %197
store i32 %195, i32* %198
br label %199
199: ; preds = %185
%200 = load i32, i32* %21
%201 = add nsw i32 %200, 1
store i32 %201, i32* %21
br label %182
202: ; preds = %182
%203 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%204 = load i32, i32* %6
%205 = call i64 @omp_target_is_present(i32* %203, i32 %204)
%206 = icmp ne i64 %205, 0
br i1 %206, label %207, label %218
207: ; preds = %202
%208 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.15, i64 0, i64 0))
%209 = getelementptr inbounds [1024 x i32], [1024 x i32]* %8, i64 0, i64 0
%210 = load i32, i32* %6
%211 = call i32 @omp_target_disassociate_ptr(i32* %209, i32 %210)
store i32 %211, i32* %22
%212 = load i32, i32* %22
%213 = icmp ne i32 %212, 0
%214 = xor i1 %213, true
%215 = zext i1 %214 to i64
%216 = select i1 %214, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%217 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.16, i64 0, i64 0), i8* %216)
br label %218
218: ; preds = %207, %202
%219 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%220 = load i32, i32* %6
%221 = call i64 @omp_target_is_present(i32* %219, i32 %220)
%222 = icmp ne i64 %221, 0
br i1 %222, label %223, label %234
223: ; preds = %218
%224 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.17, i64 0, i64 0))
%225 = getelementptr inbounds [1024 x i32], [1024 x i32]* %9, i64 0, i64 0
%226 = load i32, i32* %6
%227 = call i32 @omp_target_disassociate_ptr(i32* %225, i32 %226)
store i32 %227, i32* %23
%228 = load i32, i32* %23
%229 = icmp ne i32 %228, 0
%230 = xor i1 %229, true
%231 = zext i1 %230 to i64
%232 = select i1 %230, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%233 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.18, i64 0, i64 0), i8* %232)
br label %234
234: ; preds = %223, %218
store i32 0, i32* %17
store i32 0, i32* %24
br label %235
235: ; preds = %250, %234
%236 = load i32, i32* %24
%237 = icmp slt i32 %236, 1024
br i1 %237, label %238, label %253
238: ; preds = %235
%239 = load i32, i32* %24
%240 = sext i32 %239 to i64
%241 = getelementptr inbounds [1024 x i32], [1024 x i32]* %7, i64 0, i64 %240
%242 = load i32, i32* %241
%243 = load i32, i32* %24
%244 = add nsw i32 %243, 2
%245 = icmp ne i32 %242, %244
br i1 %245, label %246, label %249
246: ; preds = %238
%247 = load i32, i32* %17
%248 = add nsw i32 %247, 1
store i32 %248, i32* %17
br label %249
249: ; preds = %246, %238
br label %250
250: ; preds = %249
%251 = load i32, i32* %24
%252 = add nsw i32 %251, 1
store i32 %252, i32* %24
br label %235
253: ; preds = %235
%254 = load i32, i32* %17
%255 = icmp ne i32 %254, 0
br i1 %255, label %256, label %258
256: ; preds = %253
%257 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.19, i64 0, i64 0))
br label %260
258: ; preds = %253
%259 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.20, i64 0, i64 0))
br label %260
260: ; preds = %258, %256
%261 = load i32*, i32** %13
%262 = load i32, i32* %6
%263 = call i32 @omp_target_free(i32* %261, i32 %262)
%264 = load i32*, i32** %14
%265 = load i32, i32* %6
%266 = call i32 @omp_target_free(i32* %264, i32 %265)
%267 = load i32*, i32** %15
%268 = load i32, i32* %6
%269 = call i32 @omp_target_free(i32* %267, i32 %268)
%270 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.21, i64 0, i64 0))
ret i32 0
}

LLVM IR (-O2):
@.str = [20 x i8] c"Initial device: %d\0A\00"
@.str.1 = [21 x i8] c"omp_target_alloc %s\0A\00"
@.str.2 = [10 x i8] c"succeeded\00"
@.str.3 = [7 x i8] c"failed\00"
@.str.7 = [31 x i8] c"omp_target_associate_ptr B %s\0A\00"
@.str.9 = [31 x i8] c"omp_target_associate_ptr C %s\0A\00"
@.str.10 = [36 x i8] c"Inside target data: A is%s present\0A\00"
@.str.11 = [1 x i8] zeroinitializer
@.str.12 = [5 x i8] c" not\00"
@.str.13 = [36 x i8] c"Inside target data: B is%s present\0A\00"
@.str.14 = [36 x i8] c"Inside target data: C is%s present\0A\00"
@.str.16 = [34 x i8] c"omp_target_disassociate_ptr B %s\0A\00"
@.str.18 = [34 x i8] c"omp_target_disassociate_ptr C %s\0A\00"
@str = [34 x i8] c"Test omp_target_memcpy: Succeeded\00"
@str.22 = [36 x i8] c"B is not present, associating it...\00"
@str.23 = [36 x i8] c"C is not present, associating it...\00"
@str.24 = [41 x i8] c"Test omp_target_associate_ptr: Succeeded\00"
@str.25 = [6 x i8] c"Done!\00"
@str.26 = [38 x i8] c"Test omp_target_associate_ptr: Failed\00"
@str.27 = [35 x i8] c"C is present, disassociating it...\00"
@str.28 = [35 x i8] c"B is present, disassociating it...\00"
@str.29 = [31 x i8] c"Test omp_target_memcpy: Failed\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca [1024 x i32]
%4 = alloca [1024 x i32]
%5 = alloca [1024 x i32]
%6 = tail call i32 (...) @omp_get_default_device()
%7 = tail call i32 @__tgt_register_requires(i32 8)
%8 = tail call i32 (...) @omp_get_initial_device()
%9 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %8)
%10 = bitcast [1024 x i32]* %3 to i8*
%11 = bitcast [1024 x i32]* %4 to i8*
%12 = bitcast [1024 x i32]* %5 to i8*
%13 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 0
%14 = getelementptr inbounds [1024 x i32], [1024 x i32]* %4, i64 0, i64 0
%15 = getelementptr inbounds [1024 x i32], [1024 x i32]* %5, i64 0, i64 0
%16 = call i32 @init(i32* %13, i32* %14, i32* %15)
%17 = call i64 @omp_target_alloc(i32 4096, i32 %6)
%18 = inttoptr i64 %17 to i32*
%19 = inttoptr i64 %17 to i8*
%20 = call i64 @omp_target_alloc(i32 4096, i32 %6)
%21 = inttoptr i64 %20 to i32*
%22 = call i64 @omp_target_alloc(i32 4096, i32 %6)
%23 = inttoptr i64 %22 to i32*
%24 = icmp ne i64 %17, 0
%25 = icmp ne i64 %20, 0
%26 = select i1 %24, i1 %25, i1 false
%27 = icmp eq i64 %22, 0
%28 = select i1 %27, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0)
%29 = select i1 %26, i8* %28, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%30 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i8* %29)
%31 = call i32 (...) @omp_get_initial_device()
%32 = call i32 @omp_target_memcpy(i32* %21, i32* %14, i32 4096, i32 0, i32 0, i32 %6, i32 %31)
%33 = call i32 (...) @omp_get_initial_device()
%34 = call i32 @omp_target_memcpy(i32* %23, i32* %15, i32 4096, i32 0, i32 0, i32 %6, i32 %33)
%35 = inttoptr i64 %22 to i8*
%36 = inttoptr i64 %20 to i8*
%37 = getelementptr i32, i32* %18, i64 1024
%38 = bitcast i32* %37 to i8*
%39 = getelementptr i32, i32* %21, i64 1024
%40 = bitcast i32* %39 to i8*
%41 = getelementptr i32, i32* %23, i64 1024
%42 = bitcast i32* %41 to i8*
%43 = icmp ult i8* %19, %40
%44 = icmp ult i8* %36, %38
%45 = and i1 %43, %44
%46 = icmp ult i8* %19, %42
%47 = icmp ult i8* %35, %38
%48 = and i1 %46, %47
%49 = or i1 %45, %48
br i1 %49, label %98, label %50
50: ; preds = %2, %50
%51 = phi i64 [ %93, %50 ], [ 0, %2 ]
%52 = getelementptr inbounds i32, i32* %21, i64 %51
%53 = bitcast i32* %52 to <4 x i32>*
%54 = load <4 x i32>, <4 x i32>* %53
%55 = getelementptr inbounds i32, i32* %52, i64 4
%56 = bitcast i32* %55 to <4 x i32>*
%57 = load <4 x i32>, <4 x i32>* %56
%58 = getelementptr inbounds i32, i32* %23, i64 %51
%59 = bitcast i32* %58 to <4 x i32>*
%60 = load <4 x i32>, <4 x i32>* %59
%61 = getelementptr inbounds i32, i32* %58, i64 4
%62 = bitcast i32* %61 to <4 x i32>*
%63 = load <4 x i32>, <4 x i32>* %62
%64 = add <4 x i32> %54, <i32 1, i32 1, i32 1, i32 1>
%65 = add <4 x i32> %57, <i32 1, i32 1, i32 1, i32 1>
%66 = add <4 x i32> %64, %60
%67 = add <4 x i32> %65, %63
%68 = getelementptr inbounds i32, i32* %18, i64 %51
%69 = bitcast i32* %68 to <4 x i32>*
store <4 x i32> %66, <4 x i32>* %69
%70 = getelementptr inbounds i32, i32* %68, i64 4
%71 = bitcast i32* %70 to <4 x i32>*
store <4 x i32> %67, <4 x i32>* %71
%72 = or i64 %51, 8
%73 = getelementptr inbounds i32, i32* %21, i64 %72
%74 = bitcast i32* %73 to <4 x i32>*
%75 = load <4 x i32>, <4 x i32>* %74
%76 = getelementptr inbounds i32, i32* %73, i64 4
%77 = bitcast i32* %76 to <4 x i32>*
%78 = load <4 x i32>, <4 x i32>* %77
%79 = getelementptr inbounds i32, i32* %23, i64 %72
%80 = bitcast i32* %79 to <4 x i32>*
%81 = load <4 x i32>, <4 x i32>* %80
%82 = getelementptr inbounds i32, i32* %79, i64 4
%83 = bitcast i32* %82 to <4 x i32>*
%84 = load <4 x i32>, <4 x i32>* %83
%85 = add <4 x i32> %75, <i32 1, i32 1, i32 1, i32 1>
%86 = add <4 x i32> %78, <i32 1, i32 1, i32 1, i32 1>
%87 = add <4 x i32> %85, %81
%88 = add <4 x i32> %86, %84
%89 = getelementptr inbounds i32, i32* %18, i64 %72
%90 = bitcast i32* %89 to <4 x i32>*
store <4 x i32> %87, <4 x i32>* %90
%91 = getelementptr inbounds i32, i32* %89, i64 4
%92 = bitcast i32* %91 to <4 x i32>*
store <4 x i32> %88, <4 x i32>* %92
%93 = add nuw nsw i64 %51, 16
%94 = icmp eq i64 %93, 1024
br i1 %94, label %95, label %50
95: ; preds = %50, %98
%96 = call i32 (...) @omp_get_initial_device()
%97 = call i32 @omp_target_memcpy(i32* %13, i32* %18, i32 4096, i32 0, i32 0, i32 %96, i32 %6)
br label %124
98: ; preds = %2, %98
%99 = phi i64 [ %115, %98 ], [ 0, %2 ]
%100 = getelementptr inbounds i32, i32* %21, i64 %99
%101 = load i32, i32* %100
%102 = getelementptr inbounds i32, i32* %23, i64 %99
%103 = load i32, i32* %102
%104 = add i32 %101, 1
%105 = add i32 %104, %103
%106 = getelementptr inbounds i32, i32* %18, i64 %99
store i32 %105, i32* %106
%107 = or i64 %99, 1
%108 = getelementptr inbounds i32, i32* %21, i64 %107
%109 = load i32, i32* %108
%110 = getelementptr inbounds i32, i32* %23, i64 %107
%111 = load i32, i32* %110
%112 = add i32 %109, 1
%113 = add i32 %112, %111
%114 = getelementptr inbounds i32, i32* %18, i64 %107
store i32 %113, i32* %114
%115 = add nuw nsw i64 %99, 2
%116 = icmp eq i64 %115, 1024
br i1 %116, label %95, label %98
117: ; preds = %124
%118 = icmp eq i32 %157, 0
%119 = select i1 %118, i8* getelementptr inbounds ([34 x i8], [34 x i8]* @str, i64 0, i64 0), i8* getelementptr inbounds ([31 x i8], [31 x i8]* @str.29, i64 0, i64 0)
%120 = call i32 @puts(i8* dereferenceable(1) %119)
%121 = call i32 @init(i32* %13, i32* %14, i32* %15)
%122 = call i64 @omp_target_is_present(i32* %14, i32 %6)
%123 = icmp eq i64 %122, 0
br i1 %123, label %160, label %166
124: ; preds = %124, %95
%125 = phi i64 [ 0, %95 ], [ %158, %124 ]
%126 = phi i32 [ 0, %95 ], [ %157, %124 ]
%127 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %125
%128 = load i32, i32* %127
%129 = or i64 %125, 2
%130 = zext i32 %128 to i64
%131 = icmp ne i64 %129, %130
%132 = zext i1 %131 to i32
%133 = add nuw nsw i32 %126, %132
%134 = or i64 %125, 1
%135 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %134
%136 = load i32, i32* %135
%137 = or i64 %125, 3
%138 = zext i32 %136 to i64
%139 = icmp ne i64 %137, %138
%140 = zext i1 %139 to i32
%141 = add nuw nsw i32 %133, %140
%142 = or i64 %125, 2
%143 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %142
%144 = load i32, i32* %143
%145 = add nuw nsw i64 %125, 4
%146 = zext i32 %144 to i64
%147 = icmp ne i64 %145, %146
%148 = zext i1 %147 to i32
%149 = add nuw nsw i32 %141, %148
%150 = or i64 %125, 3
%151 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %150
%152 = load i32, i32* %151
%153 = add nuw nsw i64 %125, 5
%154 = zext i32 %152 to i64
%155 = icmp ne i64 %153, %154
%156 = zext i1 %155 to i32
%157 = add nuw nsw i32 %149, %156
%158 = add nuw nsw i64 %125, 4
%159 = icmp eq i64 %158, 1024
br i1 %159, label %117, label %124
160: ; preds = %117
%161 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @str.22, i64 0, i64 0))
%162 = call i32 @omp_target_associate_ptr(i32* %14, i32* %21, i32 4096, i32 0, i32 %6)
%163 = icmp eq i32 %162, 0
%164 = select i1 %163, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%165 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([31 x i8], [31 x i8]* @.str.7, i64 0, i64 0), i8* %164)
br label %166
166: ; preds = %160, %117
%167 = call i64 @omp_target_is_present(i32* %15, i32 %6)
%168 = icmp eq i64 %167, 0
br i1 %168, label %169, label %175
169: ; preds = %166
%170 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @str.23, i64 0, i64 0))
%171 = call i32 @omp_target_associate_ptr(i32* %15, i32* %23, i32 4096, i32 0, i32 %6)
%172 = icmp eq i32 %171, 0
%173 = select i1 %172, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%174 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([31 x i8], [31 x i8]* @.str.9, i64 0, i64 0), i8* %173)
br label %175
175: ; preds = %169, %166
%176 = call i64 @omp_target_is_present(i32* %13, i32 %6)
%177 = icmp eq i64 %176, 0
%178 = select i1 %177, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0)
%179 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @.str.10, i64 0, i64 0), i8* %178)
%180 = call i64 @omp_target_is_present(i32* %14, i32 %6)
%181 = icmp eq i64 %180, 0
%182 = select i1 %181, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0)
%183 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @.str.13, i64 0, i64 0), i8* %182)
%184 = call i64 @omp_target_is_present(i32* %15, i32 %6)
%185 = icmp eq i64 %184, 0
%186 = select i1 %185, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.11, i64 0, i64 0)
%187 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @.str.14, i64 0, i64 0), i8* %186)
br label %188
188: ; preds = %188, %175
%189 = phi i64 [ 0, %175 ], [ %231, %188 ]
%190 = getelementptr inbounds [1024 x i32], [1024 x i32]* %4, i64 0, i64 %189
%191 = bitcast i32* %190 to <4 x i32>*
%192 = load <4 x i32>, <4 x i32>* %191
%193 = getelementptr inbounds i32, i32* %190, i64 4
%194 = bitcast i32* %193 to <4 x i32>*
%195 = load <4 x i32>, <4 x i32>* %194
%196 = getelementptr inbounds [1024 x i32], [1024 x i32]* %5, i64 0, i64 %189
%197 = bitcast i32* %196 to <4 x i32>*
%198 = load <4 x i32>, <4 x i32>* %197
%199 = getelementptr inbounds i32, i32* %196, i64 4
%200 = bitcast i32* %199 to <4 x i32>*
%201 = load <4 x i32>, <4 x i32>* %200
%202 = add <4 x i32> %192, <i32 1, i32 1, i32 1, i32 1>
%203 = add <4 x i32> %195, <i32 1, i32 1, i32 1, i32 1>
%204 = add <4 x i32> %202, %198
%205 = add <4 x i32> %203, %201
%206 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %189
%207 = bitcast i32* %206 to <4 x i32>*
store <4 x i32> %204, <4 x i32>* %207
%208 = getelementptr inbounds i32, i32* %206, i64 4
%209 = bitcast i32* %208 to <4 x i32>*
store <4 x i32> %205, <4 x i32>* %209
%210 = or i64 %189, 8
%211 = getelementptr inbounds [1024 x i32], [1024 x i32]* %4, i64 0, i64 %210
%212 = bitcast i32* %211 to <4 x i32>*
%213 = load <4 x i32>, <4 x i32>* %212
%214 = getelementptr inbounds i32, i32* %211, i64 4
%215 = bitcast i32* %214 to <4 x i32>*
%216 = load <4 x i32>, <4 x i32>* %215
%217 = getelementptr inbounds [1024 x i32], [1024 x i32]* %5, i64 0, i64 %210
%218 = bitcast i32* %217 to <4 x i32>*
%219 = load <4 x i32>, <4 x i32>* %218
%220 = getelementptr inbounds i32, i32* %217, i64 4
%221 = bitcast i32* %220 to <4 x i32>*
%222 = load <4 x i32>, <4 x i32>* %221
%223 = add <4 x i32> %213, <i32 1, i32 1, i32 1, i32 1>
%224 = add <4 x i32> %216, <i32 1, i32 1, i32 1, i32 1>
%225 = add <4 x i32> %223, %219
%226 = add <4 x i32> %224, %222
%227 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %210
%228 = bitcast i32* %227 to <4 x i32>*
store <4 x i32> %225, <4 x i32>* %228
%229 = getelementptr inbounds i32, i32* %227, i64 4
%230 = bitcast i32* %229 to <4 x i32>*
store <4 x i32> %226, <4 x i32>* %230
%231 = add nuw nsw i64 %189, 16
%232 = icmp eq i64 %231, 1024
br i1 %232, label %233, label %188
233: ; preds = %188
%234 = call i64 @omp_target_is_present(i32* %14, i32 %6)
%235 = icmp eq i64 %234, 0
br i1 %235, label %242, label %236
236: ; preds = %233
%237 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([35 x i8], [35 x i8]* @str.28, i64 0, i64 0))
%238 = call i32 @omp_target_disassociate_ptr(i32* %14, i32 %6)
%239 = icmp eq i32 %238, 0
%240 = select i1 %239, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%241 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([34 x i8], [34 x i8]* @.str.16, i64 0, i64 0), i8* %240)
br label %242
242: ; preds = %236, %233
%243 = call i64 @omp_target_is_present(i32* %15, i32 %6)
%244 = icmp eq i64 %243, 0
br i1 %244, label %245, label %246
245: ; preds = %246, %242
br label %260
246: ; preds = %242
%247 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([35 x i8], [35 x i8]* @str.27, i64 0, i64 0))
%248 = call i32 @omp_target_disassociate_ptr(i32* %15, i32 %6)
%249 = icmp eq i32 %248, 0
%250 = select i1 %249, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i64 0, i64 0)
%251 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([34 x i8], [34 x i8]* @.str.18, i64 0, i64 0), i8* %250)
br label %245
252: ; preds = %260
%253 = icmp eq i32 %293, 0
%254 = select i1 %253, i8* getelementptr inbounds ([41 x i8], [41 x i8]* @str.24, i64 0, i64 0), i8* getelementptr inbounds ([38 x i8], [38 x i8]* @str.26, i64 0, i64 0)
%255 = call i32 @puts(i8* dereferenceable(1) %254)
%256 = call i32 @omp_target_free(i32* %18, i32 %6)
%257 = call i32 @omp_target_free(i32* %21, i32 %6)
%258 = call i32 @omp_target_free(i32* %23, i32 %6)
%259 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @str.25, i64 0, i64 0))
ret i32 0
260: ; preds = %260, %245
%261 = phi i64 [ 0, %245 ], [ %294, %260 ]
%262 = phi i32 [ 0, %245 ], [ %293, %260 ]
%263 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %261
%264 = load i32, i32* %263
%265 = or i64 %261, 2
%266 = zext i32 %264 to i64
%267 = icmp ne i64 %265, %266
%268 = zext i1 %267 to i32
%269 = add nuw nsw i32 %262, %268
%270 = or i64 %261, 1
%271 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %270
%272 = load i32, i32* %271
%273 = or i64 %261, 3
%274 = zext i32 %272 to i64
%275 = icmp ne i64 %273, %274
%276 = zext i1 %275 to i32
%277 = add nuw nsw i32 %269, %276
%278 = or i64 %261, 2
%279 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %278
%280 = load i32, i32* %279
%281 = add nuw nsw i64 %261, 4
%282 = zext i32 %280 to i64
%283 = icmp ne i64 %281, %282
%284 = zext i1 %283 to i32
%285 = add nuw nsw i32 %277, %284
%286 = or i64 %261, 3
%287 = getelementptr inbounds [1024 x i32], [1024 x i32]* %3, i64 0, i64 %286
%288 = load i32, i32* %287
%289 = add nuw nsw i64 %261, 5
%290 = zext i32 %288 to i64
%291 = icmp ne i64 %289, %290
%292 = zext i1 %291 to i32
%293 = add nuw nsw i32 %285, %292
%294 = add nuw nsw i64 %261, 4
%295 = icmp eq i64 %294, 1024
br i1 %295, label %252, label %260
}