| /* { dg-additional-options "-fdump-tree-gimple" } */ |
| |
| // Do diagnostic check / dump check only; |
| // Note: this test should work as run-test as well. |
| |
| #if 0 |
| #include <omp.h> |
| #else |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| extern int omp_get_default_device (); |
| extern int omp_get_num_devices (); |
| #ifdef __cplusplus |
| } |
| #endif |
| #endif |
| |
| |
| void f(int *x, int *y); |
| #pragma omp declare variant(f) adjust_args(need_device_ptr: x, y) match(construct={dispatch}) |
| void g(int *x, int *y); |
| |
| void |
| sub (int *a, int *b) |
| { |
| // The has_device_addr is a bit questionable as the caller is not actually |
| // passing a device address - but we cannot pass one because of the |
| // following: |
| // |
| // As for 'b' need_device_ptr has been specified and 'b' is not |
| // in the semantic requirement set 'is_device_ptr' (and only in 'has_device_addr') |
| // "the argument is converted in the same manner that a use_device_ptr clause |
| // on a target_data construct converts its pointer" |
| #pragma omp dispatch is_device_ptr(a), has_device_addr(b) /* { dg-warning "'has_device_addr' for 'b' does not imply 'is_device_ptr' required for 'need_device_ptr' \\\[-Wopenmp\\\]" } */ |
| g(a, b); |
| } |
| |
| void |
| f(int *from, int *to) |
| { |
| static int cnt = 0; |
| cnt++; |
| if (cnt >= 3) |
| { |
| if (omp_get_default_device () != -1 |
| && omp_get_default_device () < omp_get_num_devices ()) |
| { |
| // On offload device but not mapped |
| if (from != (void *)0L) // Not mapped |
| __builtin_abort (); |
| } |
| else if (from[0] != 5) |
| __builtin_abort (); |
| return; |
| } |
| #pragma omp target is_device_ptr(from, to) |
| { |
| to[0] = from[0] * 10; |
| to[1] = from[1] * 10; |
| } |
| } |
| |
| int |
| main () |
| { |
| int A[2], B[2] = {123, 456}, C[1] = {5}; |
| int *p = A; |
| #pragma omp target enter data map(A, B) |
| |
| /* Note: We don't add 'use_device_addr(B)' here; |
| if we do, it will fail with an illegal memory access (why?). */ |
| #pragma omp target data use_device_ptr(p) |
| { |
| sub(p, B); |
| sub(C, B); /* C is not mapped -> 'from' ptr == NULL */ |
| } |
| |
| #pragma omp target exit data map(A, B) |
| } |
| |
| // { dg-final { scan-tree-dump-times "#pragma omp dispatch has_device_addr\\(b\\) is_device_ptr\\(a\\)" 1 "gimple" } } |
| // { dg-final { scan-tree-dump-times "__builtin_omp_get_mapped_ptr" 1 "gimple" } } |
| // { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(b" 1 "gimple" } } |
| // { dg-final { scan-tree-dump-times "f \\(a, D\\.\[0-9\]+\\);" 1 "gimple" } } |