xref: /llvm-project/offload/test/offloading/requires.c (revision 13dcc95dcd4999ff99f2de89d881f1aed5b21709)
1 // clang-format off
2 // RUN: %libomptarget-compile-generic -DREQ=1 && %libomptarget-run-generic 2>&1 | %fcheck-generic -check-prefix=GOOD
3 // RUN: %libomptarget-compile-generic -DREQ=2 && not %libomptarget-run-generic 2>&1 | %fcheck-generic -check-prefix=BAD
4 // clang-format on
5 
6 /*
7   Test for the 'requires' clause check.
8   When a target region is used, the requires flags are set in the
9   runtime for the entire compilation unit. If the flags are set again,
10   (for whatever reason) the set must be consistent with previously
11   set values.
12 */
13 #include <omp.h>
14 #include <stdio.h>
15 
16 // ---------------------------------------------------------------------------
17 // Various definitions copied from OpenMP RTL
18 
19 typedef struct {
20   uint64_t Reserved;
21   uint16_t Version;
22   uint16_t Kind;
23   uint32_t Flags;
24   void *Address;
25   char *SymbolName;
26   uint64_t Size;
27   uint64_t Data;
28   void *AuxAddr;
29 } __tgt_offload_entry;
30 
31 enum Flags {
32   OMP_REGISTER_REQUIRES = 0x10,
33 };
34 
35 typedef struct {
36   void *ImageStart;
37   void *ImageEnd;
38   __tgt_offload_entry *EntriesBegin;
39   __tgt_offload_entry *EntriesEnd;
40 } __tgt_device_image;
41 
42 typedef struct {
43   int32_t NumDeviceImages;
44   __tgt_device_image *DeviceImages;
45   __tgt_offload_entry *HostEntriesBegin;
46   __tgt_offload_entry *HostEntriesEnd;
47 } __tgt_bin_desc;
48 
49 void __tgt_register_lib(__tgt_bin_desc *Desc);
50 void __tgt_unregister_lib(__tgt_bin_desc *Desc);
51 
52 // End of definitions copied from OpenMP RTL.
53 // ---------------------------------------------------------------------------
54 
55 void run_reg_requires() {
56   // Before the target region is registered, the requires registers the status
57   // of the requires clauses. Since there are no requires clauses in this file
58   // the flags state can only be OMP_REQ_NONE i.e. 1.
59 
60   // This is the 2nd time this function is called so it should print SUCCESS if
61   // REQ is compatible with `1` and otherwise cause an error.
62   __tgt_offload_entry entries[] = {
63       {0, 0, 1, OMP_REGISTER_REQUIRES, NULL, "", 0, 1, NULL},
64       {0, 0, 1, OMP_REGISTER_REQUIRES, NULL, "", 0, REQ, NULL}};
65   __tgt_device_image image = {NULL, NULL, &entries[0], &entries[1] + 1};
66   __tgt_bin_desc bin = {1, &image, &entries[0], &entries[1] + 1};
67 
68   __tgt_register_lib(&bin);
69 
70   printf("SUCCESS");
71 
72   __tgt_unregister_lib(&bin);
73 
74   // clang-format off
75   // GOOD: SUCCESS
76   // BAD: omptarget fatal error 2: '#pragma omp requires reverse_offload' not used consistently!
77   // clang-format on
78 }
79 
80 // ---------------------------------------------------------------------------
81 int main() {
82   run_reg_requires();
83 
84 // This also runs reg requires for the first time.
85 #pragma omp target
86   {
87   }
88 
89   return 0;
90 }
91